首页 > 解决方案 > 带有 WHERE 子句的 Rails 索引操作

问题描述

我正在尝试学习 Rails,所以我知道我可能会遗漏一些简单的概念。

我有一个员工名单,每个人都属于一个给定的项目。登录系统的用户只能查看/管理属于其项目的员工(用户也附加到给定项目)。这意味着我在 User 和 Staff 模型中都有 project_id。

我希望 current_user 只能查看他/她自己项目的记录。我已经在 Michael Hartl 的书中实现了身份验证系统,所以我已经定义了一个 current_user 方法并且可以正常工作。

这是我的索引操作:

def index
@staffs = Staff.where("current_user.project_id = ?", 'staff.project_id') 
end

但是,我收到一个错误:

no such column: current_user.project_id

我没主意了。我该如何实施?

标签: ruby-on-rails

解决方案


你会想做:

def index
    @staffs = Staff.where(project_id: current_user.project_id)
end

这将执行 sql 代码select … from staff where staff.project_id = 123;,假设 的值为current_user.project_id123。这是因为 where 方法负责将您提供的键 (project_id) 映射到值 (current_user.project_id 的值)。

来自您的 where 方法的 sql 将是select … from staff where current_user.project_id = "staff.project_id";. 数据库列应该是 where 方法的第一部分,而值是第二部分。

您可以将其添加到您的基本控制器 (ApplicationController) 以使其随处可用,例如:

class ApplicationController < ActionController::Base
    before_action :current_staff

    def index
    end

    def current_staff
        @staffs = Staff.where(project_id: current_user.project_id) if current_user # make sure user is signed in
    end
end

如果你想在选择中使用它,你可以添加一个这样的辅助方法:

module ApplicationHelper
    def options_for_staff_projects_select(selected = nil)
        project_ids = @staffs.collect(:project_id) # get list of project ids from staff
        options = Project.where(id: project_ids).map { |x| [x.name, x.id] }

        options_for_select options, selected
    end
end

# in your form call:
<%= f.select :project_id, options_for_staff_projects_select(model.project_id), include_blank: 'Choose Project' %>

推荐阅读