Jer*_*iko 9 activerecord arel ruby-on-rails-3
我的工作是有模型的应用程序User和Project,并User可以被分配到多个ProjectS,通过ProjectUser与一个角色(如开发人员,设计师).
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
Run Code Online (Sandbox Code Playgroud)
我可以打电话@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'
Run Code Online (Sandbox Code Playgroud)
我目前有以下代码:
has_many :developers, :through => :project_users, :source => :user,
:class_name => "User",
:conditions => ['project_users.role = ?','Developer']
Run Code Online (Sandbox Code Playgroud)
但这只是单向提取,并没有给我太多其他东西 - 我无法建立或分配或任何东西.
我正在尝试一些我认为可能有用的更复杂的逻辑,但我会欣赏一些指示:
has_many :developer_assignments, :source => :project_user,
:conditions => { :role => 'Developer' }
has_many :developers, :through => :developer_assignments # class_name?
Run Code Online (Sandbox Code Playgroud)
有什么建议?谢谢!
Hec*_*lot 12
has_many接受可以定义/覆盖关联方法的块.这将允许您为其创建自定义方法<<.我为你创建了一个小例子,你可以用类似的方式创建构建.
# 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
Run Code Online (Sandbox Code Playgroud)
现在,您可以@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, :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
Run Code Online (Sandbox Code Playgroud)
回首这一切上面似乎并不像铁轨的方式做事.确定范围应该可以使构建和创建命令工作而无需重新定义所有内容.
希望这可以帮助!
请参阅以下文章,了解有关多态关联的一个很好的示例。这应该可以帮助您实现以下目标:
@project.developers
# returns @project.users, but only where ProjectUser.role = 'Developer'
@project.designers << @user
# creates a ProjectUser for @project, @user with role 'Designer'
Run Code Online (Sandbox Code Playgroud)
范围将为您提供一种干净的实施方式@user.development_projects,但可能需要更多技巧才能获得<<操作员。
| 归档时间: |
|
| 查看次数: |
6708 次 |
| 最近记录: |