这是我在StackOverflow上的第一个问题......请保持温和。我只是选择了Ruby on Rails,而且我主要是通过我的第一个学习项目,但我似乎无法以一种与will_paginate原生工作的方式构建这个查询。
我有一个包含用户,组和计算机的模型结构。用户组与计算机组之间没有区别。组是一个组,通过两个has_many通过关系包括许多用户和/或计算机。计算机和/或用户可以在许多组中。这是我的模特:
class Group < ActiveRecord::Base
attr_accessible :name
has_many :user_memberships
has_many :users, :through => :user_memberships
has_many :computer_memberships
has_many :computers, :through => :computer_memberships
validates :name, presence: true, length: { maximum: 50 }, uniqueness: { case_sensitive: false }
end
class ComputerMembership < ActiveRecord::Base
attr_accessible :computer_id, :group_id
belongs_to :computer
belongs_to :group
validates_uniqueness_of :computer_id, :scope => :group_id
validates_presence_of :computer
validates_presence_of :group
end
class UserMembership < ActiveRecord::Base
attr_accessible :group_id, :user_id
belongs_to :user
belongs_to :group
validates_uniqueness_of :user_id, :scope => :group_id
validates_presence_of :user
validates_presence_of :group
end
用户和群组(为简洁起见,仅包含has_many部分):
class User < ActiveRecord::Base
...
has_many :user_memberships, dependent: :destroy
has_many :groups, through: :user_memberships
...
end
class Computer < ActiveRecord::Base
...
has_many :computer_memberships, dependent: :destroy
has_many :groups, through: :computer_memberships
...
end
我正在尝试构建一个查询,以仅检索current_user也是其成员的组中的(不同)计算机。我正在我的控制器中尝试这样的事情:
def computers_in_users_groups_or_all_if_admin
unless admin?
computerarray = Array.new
current_user.group_ids.each do |id|
computerarray = computerarray | Group.find(id).computer_ids
end
@computers = Computer.find(computerarray).paginate(page: params[:page], per_page: 30).order('sn')
else
flash.now[:notice] = "You are seeing all computers because you are an administrator."
@computers = Computer.paginate(page: params[:page], per_page: 30).order('sn')
end
end
它似乎正在工作,但它返回一个不能与will_paginate一起使用的数组,除非我明确包含数组支持。 will_paginate / array似乎也不支持.order方法。作为Rails和ActiveRecord的新手,我知道必须有更好的方法来执行此查询。任何帮助将不胜感激。
谢谢!
答案 0 :(得分:1)
首先,为什么不在分页之前订购?
但是,使用Rails和ActiveRecord处理此问题的更好,更惯用的方法是named scope,类似于
# computer.rb
class Computer
scope :all_for_user, lambda { |user| user.admin? ? Computer.paginate(page: params[:page], per_page: 30) : user.groups.computers.paginate(page: params[:page], per_page: 30)
end
# computer_controller.rb
Computer.all_for_user(current_user)
您需要确保设置实体association code。您可能需要User
到has_and_belongs_to_many :groups
以及has_many :computers, :through => :groups
这大大简化了查询和逻辑。
N.B。上面的代码都是我的头顶而未经测试,但它应该指向正确的方向。
答案 1 :(得分:0)
使用上面的jxp指导,虽然我没有制作一个范围,因为我只需要在一个地方,我回去重温我的模型。我刚刚添加了
has_many :computers, through: :groups, :uniq => true
到我的用户模型,然后可以调用:
@computers = current_user.computers.paginate(page: params[:page], per_page: 15).order('sn')
现在工作正常。 :d