ruby-on-rails - Ruby on Rails 让外键发挥作用

标签 ruby-on-rails rails-activerecord

我觉得这是一个我无法弄清楚的简单错误,但我没有在网上找到任何内容来帮助解释我做错了什么。我在 Ruby on Rails 应用程序中创建了三个表:

Facility
 facility_name - string
 address       - string
 city_id       - integer
 state_id      - integer
 
 and foreign keys: cities, states

City
  city_name    - integer
  state_id     - integer

State
  state_short  - string
  state_long   - string

我将模型定义为:

class Facility < ApplicationRecord
  has_one :city
  has_one :state
end


class City < ApplicationRecord
  belongs_to :state
  belongs_to :facility
end

class State < ApplicationRecord
  has_many :cities
  belongs_to :facility
end

我认为我可以通过 Rails 控制台上的以下代码在设施内显示城市和州:

x = Facility.first
x.city_name
x.state_long

但是这两个代码都会出错。我是否错误地认为,通过在设施表中包含 city_idstate_id 以及上述关系,我应该能够获取 city_namestate_long 来自各自的表?

最佳答案

class Facility < ApplicationRecord
  has_one :city
  has_one :state
end

这意味着citiesstates表有facility_id

但是在您的架构中设施具有city_idstate_id

这意味着你需要以这种方式改变你的关联

class Facility < ApplicationRecord
  belongs_to :city
  belongs_to :state
end

class City < ApplicationRecord
  belongs_to :state
  has_one :facility
end

class State < ApplicationRecord
  has_many :cities
  has_one :facility
end

另一个选项是更改架构(如果保留关联)

facilities
-----------
facility_name
address

cities
-----------
city_name
state_id 
facility_id

states
-----------
state_short
state_long
facility_id

换句话说你need choosebelongs_tohas_one

之间

The distinction is in where you place the foreign key (it goes on the table for the class declaring the belongs_to association), but you should give some thought to the actual meaning of the data as well. The has_one relationship says that one of something is yours - that is, that something points back to you

在任何情况下,如果设施实例没有 city_namestate_long 方法,都会发生错误,因为添加关联不会定义关联模型的方法

你可以这样调用它

facility = Facility.first
facility.city.city_name
facility.state.state_long

但是可以添加这样的方法

class Facility < ApplicationRecord
  belongs_to :city
  belongs_to :state

  def city_name
    city.city_name
  end

  def state_long
    state.state_long
  end
end

或使用委托(delegate)方法

class Facility < ApplicationRecord
  belongs_to :city
  belongs_to :state

  delegate :city_name, to: :city
  delegate :state_long, to: :state
end

之后你可以这样调用它

facility = Facility.first
facility.city_name
facility.state_long

关于ruby-on-rails - Ruby on Rails 让外键发挥作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75645400/

相关文章:

ruby-on-rails - Rails Active Record 上的依赖销毁与依赖删除之间的区别

ruby-on-rails - Rails 4 中的作用域数量

ruby-on-rails - rails : Unknown attribute during model create

ruby-on-rails - 在 rails 中有状态的后台作业

ruby-on-rails - Ruby on rails 集成和功能测试之间的区别

ruby-on-rails - 如果 :string is for text, 复选框数据如何存储在 Rails 中?

ruby-on-rails - 链接表未调用 after_destroy

ruby-on-rails - 如何从 ActiveRecord 的序列化数组迁移到 Postgres 数组数据类型

ruby-on-rails - rake 数据库 :dump fails when specifying an environment

mysql - Rails 按 proc 对集合进行排序