Rails 5 Model.where(user_id) - 两个级别

时间:2017-08-04 01:18:22

标签: ruby-on-rails

措辞严厉,但我很困惑。

我有一个User模型has_many Clientshas_many statements, through: :clients,然后是statements belongs_to clientsbelongs to user

在控制台中,我可以执行我想要的所有查询。 User.statements User.client.first.statements等 - 我正在努力的是Controller restrictions

目前很简单 - 用户应该只能看到他们拥有的ClientsStatements

对于我做过的客户 客户端控制器

def index
    @clients = Client.where(user_id: current_user.id)
end

这似乎完美无缺。客户有一个user_id字段

我有点坚持如何为语句模仿这个。语句没有user_id字段。我不太确定我也想要它们,因为在不久的将来我希望客户belongs_to_many:用户和语句不受约束。

声明控制器

  def index
    @clients = Client.where(user_id: current_user.id)
    @statements = Statement.where(params[:client_id])
  end

我真的不确定要放什么 - 我知道params[:client_id]没有意义,但实现这个目标的正确方法是什么?我是不是一种不安全的方式?

客户端模型

class Client < ApplicationRecord
    has_many :statements
    has_many :client_notes, inverse_of: :client
    belongs_to :user
    validates :name, presence: true
    validates :status, presence: true
    accepts_nested_attributes_for :client_notes, reject_if: :all_blank, allow_destroy: true
end

声明模型

class Statement < ApplicationRecord
    belongs_to :client
    belongs_to :user
    validates :name, presence: true
    validates :statement_type, presence: true
    validates :client_id, presence: true
    validates :start_date, presence: true
    validates :end_date, presence: true
end

用户模型

class User < ApplicationRecord

  has_many :clients
  has_many :statements, through: :clients
end

根据下面提供的回复,我正在使用

  def index
    if params[:client][:user_id] == @current_user.id
      @clients = Client.includes(:statements).where(user_id: params[:client][:user_id])
      @statements = @clients.statements
    else
      return 'error'
    end
  end

不确定此逻辑是否正确

3 个答案:

答案 0 :(得分:2)

使用includes来避免[N + 1]次查询。

关于“用户应该只能看到他们拥有的客户和声明”

if params[:client][:user_id] == @current_user.id
  @clients = Client.includes(:statements).where(user_id: params[:client][:user_id])
  # do more
else
  # Type your error message
end

此外,您可能需要使用strong paramsscope

答案 1 :(得分:0)

最好的方法是使用包含:

@clients = Client.where(user_id: current_user.id)
@statements = Statement.includes(clients: :users}).where('users.id = ?', current_user.id)

您可以在此处查看:https://apidock.com/rails/ActiveRecord/QueryMethods/includes

答案 2 :(得分:0)

在这种情况下,感谢提醒current_user是Devise的助手,以及我展示的关系结构,它实际上就像

一样简单
def index
    @statements = current_user.statements
end

解决了我的问题。

由于@BigB引起我注意的[N+1] Queries issue,虽然这种方法有效,但我不建议进行大规模的交易。