ruby-on-rails-3 – Rails 3 has_many:通过连接表条件/范围设定

前端之家收集整理的这篇文章主要介绍了ruby-on-rails-3 – Rails 3 has_many:通过连接表条件/范围设定前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在研究一个具有User和Project模型的应用程序,并且可以通过ProjectUser将角色(例如Developer,Designer)分配给多个项目.
Project
  has_many :project_users
  has_many :users,:through => :project_users

User
  has_many :project_users
  has_many :projects,:through => :project_users

ProjectUser (user_id,project_id,role)
  belongs_to :user
  belongs_to :project

我可以调用@ project.users和@ user.projects,但是由于有不同的角色,所以我想要更加具体的关系.理想情况下,我想要做到以下几点:

@project.developers
  # returns @project.users,but only where ProjectUser.role = 'Developer'

@project.designers << @user
  # creates a ProjectUser for @project,@user with role 'Designer'

@user.development_projects
  # returns projects where @user is assigned as a 'Developer'

@user.design_projects << @project
  # creates a ProjectUser for @project,@user with role 'Designer'

我目前有以下代码

has_many :developers,:through => :project_users,:source => :user,:class_name => "User",:conditions => ['project_users.role = ?','Developer']

但这只是真正地提取单向,不给我很多其他 – 我不能建立或分配或任何东西.

我正在尝试一些更复杂的逻辑,我认为可能会工作,但会欣赏一些指针:

has_many :developer_assignments,:source => :project_user,:conditions => { :role => 'Developer' }
has_many :developers,:through => :developer_assignments # class_name?

有什么建议么?谢谢!

解决方法

has_many接受一个可以定义/覆盖关联方法的块.这将允许您为<<<创建一个自定义方法.我为您创建了一个小例子,您可以以类似的方式创建构建.
# Project.rb
has_many :developers,:conditions => "project_users.role = 'developer'" do
         def <<(developer)
           proxy_owner.project_users.create(:role => 'developer',:user => developer)
         end
       end

现在,您可以通过以下方式向您的项目添加新的开发人员:@ project.developers<< @user请求. @ project.developers给你所有的开发人员. 如果您有很多角色,那么动态创建这些has_many语句可能是有用的.

# Project.rb
ROLES = ['developer','contractor']

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

回顾上面的一切,它似乎并不像轨道做事情那样.这样做的范围应该使得可以在不重新定义所有内容的情况下获取构建和创建命令.

希望这可以帮助!

猜你在找的Ruby相关文章