构建一个结构合理的查询,为will_paginate返回一个ActiveRecord关系,而不是一个数组

时间:2012-12-30 23:28:42

标签: ruby-on-rails ruby-on-rails-3

这是我在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的新手,我知道必须有更好的方法来执行此查询。任何帮助将不胜感激。

谢谢!

2 个答案:

答案 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。您可能需要Userhas_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