用于在has_and_belongs_to_many中查询连接表的Rails方式

Lyn*_*n C 3 ruby activerecord ruby-on-rails

我有一个用户模型和一个带有has_and_belongs_to_many reliationship的角色模型.连接表是roles_users(两列 - 用户的PK和角色),没有相应的模型.

我想有一个方法返回具有给定角色的所有用户.在SQL中,它就像是

SELECT u.id FROM role.r, roles_users ru WHERE r.role_id = #{role.id} AND r.role_id = ru.role_id
Run Code Online (Sandbox Code Playgroud)

我看到Rails的activerecord有一个find_by_sql方法,但它只期望返回一个结果.

什么是"Rails方式"给我一个具有给定角色的用户列表,例如

def self.find_users_with_role(role)
  users = []
  users << # Some ActiveRecord magic or custom code here..?
end
Run Code Online (Sandbox Code Playgroud)

fl0*_*00r 9

通常,HABTM关联默认包含此方法!

IE:角色has_and_belongs_to_many:用户

您只需要为当前角色调用用户方法:

role = Role.last

users = role.users

这都是ORM魔术.不要发明你的自行车:)

更多信息http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_and_belongs_to_many


Ada*_*man 8

我假设角色位于一个名为"角色"的表中.它会是这样的:

User.all(:joins => :roles,
         :conditions => {:roles => {:id => role.id}})
Run Code Online (Sandbox Code Playgroud)

或者对于像你在那里展示的类方法一样,使用命名范围.

named_scope :with_role, lambda { |role_id| { :joins => :roles, 
                                             :conditions => {:roles => {:id => role_id} } } }
# call it like so:
User.with_role(role.id)
Run Code Online (Sandbox Code Playgroud)

这些是未经测试的示例,因此可能需要稍微调整一下.

只需选择ActiveRecord :: Base#find:http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002263

注意:join和:includes之间的区别.有一个Railscast:http://railscasts.com/episodes/181-include-vs-joins