Rails模型关联,has_many:through和has_one具有相同的模型
我有两个模型:用户和状态。 州模型记录了美国50个州中的每个州。
我希望每个用户都有两个属性:一个“主页”状态,以及许多“访问”状态。
我知道我必须建立某种模型关联来实现这一目标,但不确定何时采用最佳方法。
这是我到目前为止所拥有的,但我知道将has_many和has_one关联到同一模型一定有问题。
#user.rb class User :visits has_one :state end #visit.rb class Visit < ActiveRecord::Base belongs_to :user belongs_to :state end #state.rb class State :visits belongs_to :user end
有什么建议?
在这种情况下,您不能在单个模型上具有has_many和has_one关系。 一种解决方案是:
创建状态的静态模型,它们不需要是数据库模型,它们可以是状态模型上的静态变量: US_STATES = {'1' => 'AK', '2' => 'AL', etc}
或者您可以使用fixture来将状态表加载到数据库中(更复杂,因为您需要使用rake任务或db:seed任务将fixtures加载到db中,但很好,因为您可以使用活动记录来管理该模型)。
然后,您可以在定义home_state的用户模型上提供home_state_id,并且访问只是user_id和state_id之间的连接。
我希望每个用户都有两个属性:一个“主页”状态,以及许多“访问”状态。
在您的模型中,状态可能只是一个用户的所在地( belongs_to
)。
正确的语义将是
class User < AR::Base belongs_to :home_state, :class_name => "State", :foreign_key => "home_state_id", :inverse_of => :users_living has_and_belongs_to_many :visited_states, :through => :visits # ... end class State < AR::Base has_many :users_living, :class_name => "User", :inverse_of => :home_state # ... end
在我看来,你已经拥有的几乎是正确的,除非你将家庭状态外键存储在用户身上,如下所示:
# 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
然后,您将访问家庭状态,如下所示:
u = User.first u.state
和访问过的州,如下:
u = User.first u.states
为了清晰编程,您可以重命名关系:
# 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
您的域模型会更有意义:
u = User.first u.home_state u.visited_states s = State.first s.residents s.visitors
我希望您可能希望存储有关访问的其他信息,因此保留Visit
模型的HMT连接表将允许您执行此操作,而不是使用HABTM关系。 然后,您可以为访问添加属性:
# 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
- gmail和parse_resource gems之间的Ruby自动加载冲突
- 与同一模型的多个has_many关系
- Rails模型的默认条件
- Rails bug:accepts_nested_attributes_for没有更新我的has_many关联
- 不具有区分大小写的搜索活动记录
- 为什么ActiveRecord :: StatementInvalid:SQLite3 :: SQLException:near“)”:语法错误:INSERT INTO“user_friendships”()VALUES()
- 选择* sql query vs选择特定列sql查询
- 将查询转换为活动记录
- ActiveRecord查询:按所包含模型的总和排序