代码之家  ›  专栏  ›  技术社区  ›  ohdeargod

使用相同的操作显示所有(索引)对象,但也显示由URL参数限定范围的列表

  •  2
  • ohdeargod  · 技术社区  · 15 年前

    我有一个问题,想一个好方法来做下面的事情。我有一个非常通用的组织模型和用户模型。org has_many :users User belongs_to :org .

    我试图找到一种显示用户列表的方法,该列表不受组织限制,但也显示受组织限制的用户列表。我知道我可以筑巢的路线,只是有两条不同的路线,像

    map.resources :users
    map.resources :orgs, :has_many => :users
    

    问题是它们都返回到用户控制器中的相同操作。控制器代码开始变得非常混乱,因为我必须检查是否存在:org_id参数。然后,我必须决定是返回对用户的find调用的正常结果,还是返回范围为某个组织的find。我不确定这里的最佳解决方案是什么,或者最佳实践是什么。如果有人知道这一点,请开导我,这将是伟大的。

    4 回复  |  直到 15 年前
        1
  •  1
  •   ry.    15 年前

    另一种不使用插件的方法是 named_scope . 您可以在用户中创建一个命名作用域,如果该作用域不为空,则按组织ID进行筛选。

    class User < ActiveRecord::Base
      belongs_to :org
      named_scope :by_org, lambda{|org| org.blank? ? {} : { :conditions => ['org_id = ?', org] }}
    end
    

    在控制器中,只需使用命名的作用域。这样,如果最终在控制器中提供更多的过滤器选项,则不需要复制它们:

    class UsersController < ApplicationController
      def index
        @users = User.by_org(params[:org_id]).all
        ...
      end
    end
    
        2
  •  1
  •   Maran    15 年前

    你可能在技术层面上找不到真正的答案,但我在我的项目中使用了一个插件,它可以帮我解决这个问题。看一看 make_resourceful .

    make_resourceful do
     actions :all
     belongs_to :org
    end
    

    它将为您解决剩下的问题,不需要定义标准的CRUD操作。它甚至可以检测范围并为您确定范围。(除非这是我使用的另一个插件,我忘记了)

        3
  •  1
  •   klew    15 年前

    我用 resource_controller 大多数情况下的插件。有了它,你只需把:

    class UsersController < ApplicationController
      resource_controller
      belongs_to :org
    end
    

    它使用嵌套资源而不是嵌套资源。

    如果你不想使用额外的插件,你的控制器仍然不会很复杂。

    class UsersController < ApplicationController
      def index
        @org = Org.find(params[:org_id]) unless params[:org_id].blank?
        @users = params[:org_id].blank? ? User.all : @org.users
        ...
      end
    end
    
        4
  •  0
  •   François Beausoleil    15 年前

    我通常做的是:

    class UsersController < ApplicationController
      def index
        root = Org.find(params[:org_id]) if params[:org_id]
        root = User if root.nil?
        @users = root.all(:conditions => {...}, :order => "...")
      end
    end
    

    我基本上是在树上散步。添加条件后,我只需更改find调用的根。当我评估完条件后,我调用final find/first/all方法,我就完成了。

    如果您有多个命名作用域,这也可以工作:

    class UsersController < ApplicationController
      def index
        root = Org.find(params[:org_id]) if params[:org_id]
        root = User if root.nil?
        root = root.named(params[:name]) if params[:name]
        root = root.registered_after(params[:registered_at]) if params[:registered_at]
        # more conditions, as required
        @users = root.all(:conditions => {...}, :order => "...")
      end
    end