我正在开发一个系统,User
可以通过Wedding
模型使用Attendance
user_id
以多种方式与另一个实体wedding_id
相关联。 {1}}和role
信息。在this问题的帮助下,我找到了用Rails 4风格关联替换:conditions
的方法。我的协会现在是:
User
:
has_many :wedding_attendances
has_many :weddings,
through: :wedding_attendances
has_many :marriages,
-> { WeddingAttendance.find_by_role(:spouse) },
through: :wedding_attendances,
class_name: 'Wedding'
has_many :invitations,
-> { WeddingAttendance.find_by_role(:invitee) },
through: :wedding_attendances,
class_name: 'Wedding'
has_many :ceremonies,
-> { WeddingAttendance.find_by_role(:worker) },
through: :wedding_attendances,
class_name: 'Wedding'
Wedding
:
has_many :wedding_attendances
has_many :attendees,
through: :wedding_attendances,
class_name: 'User'
has_many :spouses,
-> { WeddingAttendance.find_by_role(:spouse) },
through: :wedding_attendances,
class_name: 'User'
has_many :invitees,
-> { WeddingAttendance.find_by_role(:invitee) },
class_name: 'User',
through: :wedding_attendances
has_many :workers,
-> { WeddingAttendance.find_by_role(:worker) },
class_name: 'User',
through: :wedding_attendances
WeddingAttendance
:
belongs_to :wedding
belongs_to :user
class << self
def roles
{
spouse: 0,
invitee: 1,
worker: 2
}
end
def find_by_role role
if role.class == Symbol
where(role: roles[role])
else
where(role: role)
end
end
end
不像我想的那么简单,但显然是正确的。或者不是,因为User.first.weddings
会引发以下错误,即使WeddingAttendance.find_by_role(:spouse)
返回正确的结果集:
NoMethodError: undefined method `to_sym' for nil:NilClass
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/reflection.rb:100:in `_reflect_on_association'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/reflection.rb:537:in `source_reflection'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/reflection.rb:697:in `check_validity!'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/associations/association.rb:25:in `initialize'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/associations/has_many_through_association.rb:9:in `initialize'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/associations.rb:155:in `new'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/associations.rb:155:in `association'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/associations/builder/association.rb:110:in `marriages'
from (irb):51
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.1.8/lib/rails/commands/console.rb:90:in `start'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.1.8/lib/rails/commands/console.rb:9:in `start'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.1.8/lib/rails/commands/commands_tasks.rb:69:in `console'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.1.8/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from c:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.1.8/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
答案 0 :(得分:2)
正如@Shadwell所提到的,您需要将source
与has_many :through
一起使用。
但是我只想创建自己的方法:
class User
has_many :wedding_attendances
has_many :weddings,
through: :wedding_attendances
def self.marriages
self.weddings.where('wedding_attendances.role = ?', WeddingAttendance.find_by_role(:spouse))
end
end
这只是一个偏好,但我觉得它更容易阅读。
答案 1 :(得分:1)
我认为您需要在source:
关联中包含has_many through:
配置选项。 (您已正确使用class_name
来识别另一端的课程,但您需要的更多一点。)
来自rails guide on associations:
:source选项指定has_many:through关联的源关联名称。如果无法从关联名称自动推断源关联的名称,则只需使用此选项。
由于您的关联被称为marriages
,invitations
和ceremonies
,has_many through:
正在寻找名为WeddingAttendance
的{{1}}上的关联,{{ 1}}和marriage
,以便在关联的另一端获取invitation
实例。
如果您在ceremony
上的Wedding
个关联添加了source: :wedding
,并且through
User
个source: :user
关联through
活动记录将Wedding
能够识别它应该遵循的关联。