Rails的模型协会的has_many:通过和HAS_ONE同型号同 [英] Rails model associations, has_many :through and has_one with the same model

查看:277
本文介绍了Rails的模型协会的has_many:通过和HAS_ONE同型号同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个模式:用户和状态。该状态模型为每个美国50个州在美国的记录。

I have two models: User and State. The state model has records for each of the 50 states in the United States.

我希望每个用户有两个属性:一是家的状态,许多国家为参观

I would like each User to have two attributes: one "home" state, and many states to "visit".

我知道我必须建立某种模型关联来实现这一点,但不知道什么时候最好的办法是。

I know I have to set up some sort of model associations to achieve this, but not sure when the best approach is.

这是我迄今为止,但我知道一定有什么毛病都有的has_many和HAS_ONE联想到相同型号。

Here's what I have so far, but I know there must be something wrong with have has_many and has_one association to the same model.

#user.rb
class User < ActiveRecord::Base
   has_many :visits
   has_many :states, :through => :visits
   has_one :state
end

#visit.rb
class Visit < ActiveRecord::Base
   belongs_to :user
   belongs_to :state
end

#state.rb
class State < ActiveRecord::Base
   has many :visits
   has many :users, :through => :visits 
   belongs_to :user
end

有什么建议?

推荐答案

在我看来,你已经拥有几乎是正确的,但你将存储在像这样的用户的起始状态外键:

In my opinion what you already have is almost right, except you would store the home state foreign key on the user like thus:

# user.rb
class User < ActiveRecord::Base
  belongs_to :state
  has_many :visits
  has_many :states, through: visits
end

# visit.rb
class Visit < ActiveRecord::Base
  belongs_to :user
  belongs_to :state
end

# state.rb
class State < ActiveRecord::Base
  has_many :visits
  has_many :users, through: :visits
end

您会访问的家乡像这样的:

You would then access the home state like thus:

u = User.first
u.state

和被访问的状态,像这样的:

And the visited states, like thus:

u = User.first
u.states

有关规划清晰,你可以重命名你的关系:

For programming clarity, you can rename your relations:

# user.rb
class User < ActiveRecord::Base
  belongs_to :home_state, class_name: "State"
  has_many :visits
  has_many :visited_states, class_name: "State", through: visits
end

# state.rb
class State < ActiveRecord::Base
  has_many :residents, class_name: "User"
  has_many :visits
  has_many :visitors, class_name: "User", through: :visits
end

您的域模型会更有意义:

Your domain model would make more sense:

u = User.first
u.home_state
u.visited_states

s = State.first
s.residents
s.visitors

我想你可能会想存储关于访问的其他信息,因此保持HMT连接表的访问模式将让你做到这一点,而不是要与一个HABTM关系。然后,您可以将属性添加到请访问:

I expect you'll probably want to store additional information about the visit, so keeping the HMT join table for the Visit model will allow you to do this, rather than going with a HABTM relation. You could then add attributes to the visit:

# xxxxxxxxxxxxxxxx_create_visits.rb
class CreateVisits < ActiveRecord::Migration
  def change
    create_table :visits do |t|
      t.text :agenda
      t.datetime commenced_at
      t.datetime concluded_at
      t.references :state
      t.references :user
    end
  end
end

这篇关于Rails的模型协会的has_many:通过和HAS_ONE同型号同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆