Ste*_*Mai 70 ruby ruby-on-rails has-many has-many-through
Ruby和Rails都是新手,但我现在已经预订了教育(显然没什么意义,哈哈).
我有两个模型,Event和User通过表EventUser加入
class User < ActiveRecord::Base
has_many :event_users
has_many :events, :through => :event_users
end
class EventUser < ActiveRecord::Base
belongs_to :event
belongs_to :user
#For clarity's sake, EventUser also has a boolean column "active", among others
end
class Event < ActiveRecord::Base
has_many :event_users
has_many :users, :through => :event_users
end
Run Code Online (Sandbox Code Playgroud)
这个项目是一个日历,我必须跟踪人们注册并为特定事件划出他们的名字.我认为多对多是一个很好的方法,但我做不到这样的事情:
u = User.find :first
active_events = u.events.find_by_active(true)
Run Code Online (Sandbox Code Playgroud)
因为事件实际上没有那些额外的数据,所以EventUser模型可以.虽然我能做到:
u = User.find :first
active_events = []
u.event_users.find_by_active(true).do |eu|
active_events << eu.event
end
Run Code Online (Sandbox Code Playgroud)
这似乎与"铁路方式"相反.任何人都可以启发我,今晚(今天早上)这已经困扰了我很长时间?
Mil*_*ota 123
如何在您的用户模型中添加这样的内容?
has_many :active_events, :through => :event_users,
:class_name => "Event",
:source => :event,
:conditions => ['event_users.active = ?',true]
Run Code Online (Sandbox Code Playgroud)
之后,您应该能够通过调用以下方式为用户获取活动事件:
User.first.active_events
Run Code Online (Sandbox Code Playgroud)
msa*_*ler 22
米兰诺沃塔有一个很好的解决方案 - 但:conditions现在已被弃用,而且这:conditions => ['event_users.active = ?',true]一点似乎并不是很好.我更喜欢这样的东西:
has_many :event_users
has_many :active_event_users, -> { where active: true }, class_name: 'EventUser'
has_many :active_events, :through => :active_event_users, class_name: 'Event', :source => :event
Run Code Online (Sandbox Code Playgroud)
之后,您仍然可以通过调用以下方式为用户获取活动事件:
User.first.active_events
Run Code Online (Sandbox Code Playgroud)
Gar*_*eth 12
即使您的u.events未显式调用user_events表,由于必要的连接,该表仍隐式包含在SQL中.因此,您仍然可以在查找条件中使用该表:
u.events.find(:all, :conditions => ["user_events.active = ?", true])
Run Code Online (Sandbox Code Playgroud)
当然,如果你计划进行大量的查询,那么肯定的是,按照米兰诺沃塔的建议给它一个单独的联想,但是没有要求你那样做
嗯,User模型中的责任比实际需要的更多,没有充分的理由这样做.
我们可以先在EventUser模型中定义范围,因为它实际上属于它,例如:
class EventUser < ActiveRecord::Base
belongs_to :event
belongs_to :user
scope :active, -> { where(active: true) }
scope :inactive, -> { where(active: false) }
end
Run Code Online (Sandbox Code Playgroud)
现在,用户可以同时拥有两种事件:活动事件和非活动事件,因此我们可以在User模型中定义关系,如下所示:
class User < ActiveRecord::Base
has_many :active_event_users, -> { active }, class_name: "EventUser"
has_many :inactive_event_users, -> { inactive }, class_name: "EventUser"
has_many :inactive_events, through: :inactive_event_user,
class_name: "Event",
source: :event
has_many :active_events, through: :active_event_users,
class_name: "Event",
source: :event
end
Run Code Online (Sandbox Code Playgroud)
这种技术的优点在于,作为活动或非活动事件的功能属于EventUser模型,如果将来需要修改功能,它将仅在一个地方进行修改:EventUser模型,并且更改将反映在所有其他型号.