2015-06-08 62 views
2

我正在一個地方可以User與另一個實體通過使用user_idwedding_idrole信息Attendance模型相關聯,一個Wedding,以多種方式在系統上。在this問題的幫助下,我有點發現我用Rails 4風格的關聯替換:conditions的方法。我現在聯想它們是:的ActiveRecord,軌道4,5:的has_many:通過與範圍的條件失敗

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

我喜歡你的問題,我將在當天晚些時候的更多細節中看到它。謝謝你問 – MZaragoza

+0

它確實是'User.first.weddings'返回錯誤,而不是'User.first.marriages'?你的堆棧跟蹤似乎指的是「婚姻」。 – Shadwell

回答

1

我認爲你需要包括你的has_many through:協會一個source:配置選項。 (你已經正確使用class_name來識別另一端的類,但是你需要多一點)。

rails guide on associations

的:源選項指定源協會名稱爲的has_many:通過關聯。如果源關聯的名稱不能從關聯名稱自動推斷出來,則只需使用此選項。

因爲您的關聯被稱爲marriagesinvitationsceremonieshas_many through:正在尋找在WeddingAttendance協會呼籲marriageinvitationceremony跟隨在關聯的另一端,以獲得Wedding實例。

如果添加source: :weddingUserthrough協會和source: :userWedding活動記錄您的through協會將能夠識別它應該遵循的關聯。

+0

就是這樣。工作就像一個魅力與'源:':) –

2

正如@Shadwell提到的,您需要使用sourcehas_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 

這只是一個偏好,但我覺得它更容易閱讀。