Rails 3中的has_many:通过+连接表的条件/作用域 [英] Rails 3 has_many :through + join table conditions / scoping

查看:97
本文介绍了Rails 3中的has_many:通过+连接表的条件/作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个应用程序,具有车型用户项目用户可以通过 ProjectUser 项目 S,>,与角色(例如,开发人员,设计师)。

I'm working on an app that has the models User and Project, and User can be assigned to multiple Projects, via ProjectUser, with a role (e.g. 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 ,但既然有不同的角色,我倒是想更具体的关系了一下。理想情况下,我希望能够做到以下几点:

I can call @project.users and @user.projects, but since there are varying roles, I'd like to be a bit more specific with the relations. Ideally, I want to be able to do the following:

@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'

目前,我有以下的code:

I currently have the following code:

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

不过,这只是确实的获取单向的,并没有给我太多别的 - 我不能建立或指定或任何

But this only really does the fetching one-way, and doesn't give me much else - I can't build or assign or anything.

我在尝试一些更复杂的逻辑,我认为可能的工作,但将AP preciate一些指点:

I'm attempting some more complex logic which I think might work, but would appreciate some pointers:

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

有什么建议?谢谢!

推荐答案

的has_many 接受可以定义/覆盖方式为关联块。这将允许您创建一个自定义的方法&LT;&LT; 。我创建了一个小例子给你,你可以用类似的方式创建构建。

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

现在,您可以添加一个新的开发与您的项目中: @ project.developers&LT;&LT; @user 的要求。 <$ C C $> @ project.developers 给你所有的开发人员。

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

如果你有很多的角色,它可能是有用的动态创建这些的has_many声明。

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.

希望这有助于!

这篇关于Rails 3中的has_many:通过+连接表的条件/作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆