我正在研究一个具有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
回顾上面的一切,它似乎并不像轨道做事情那样.这样做的范围应该使得可以在不重新定义所有内容的情况下获取构建和创建命令.
希望这可以帮助!