Rails 3 has_many :through + join table conditions / scoping

前端 未结 3 356
有刺的猬
有刺的猬 2021-02-01 10:36

I\'m working on an app that has the models User and Project, and User can be assigned to multiple Projects, via Project

3条回答
  •  深忆病人
    2021-02-01 10:52

    has_many accepts a block that can define/override methods for the association. This will allow you to create a custom method for <<. I've created a small example for you, you could create build in a similar fashion.

    # Project.rb
    has_many :developers, :through => :project_users, :source => :user,
             :conditions => "project_users.role = 'developer'" do
             def <<(developer)
               proxy_owner.project_users.create(:role => 'developer', :user => developer)
             end
           end
    

    Now you can add a new developer to your your project with: @project.developers << @user as requested. @project.developers gives you all the developers.

    If you have a lot of roles, it might be useful to create these has_many statements dynamically.

    # Project.rb
    ROLES = ['developer','contractor']
    
    ROLES.each do |role|         
      self.class_eval <<-eos
        has_many :#{role.downcase}s, :through => :project_users, :source => :user,
               :conditions => "project_users.role = '#{role}'" do
                 def <<(user)
                   proxy_owner.project_users.create(:role => '#{role}', :user => user)
                 end
               end
      eos
    end
    

    Looking back at everything above it doesn't seem like the rails way of doing things. Scoping this should make it possible to get the build and create commands working without redefining everything.

    Hope this helps!

提交回复
热议问题