Rails 范围与方法值比较

bar*_*e.m 3 ruby activerecord scope ruby-on-rails

所以我对 Rails 还很陌生,ActiveRecord我需要一个范围来在Client实体之间进行过滤。基本上范围应该返回Client客户端当前状态等于某个状态对象的所有记录。

这是通过获取客户端的上一次计算state_change,然后拉着那个state_changefrom_state是一个State对象。

我已经定义了一个方法来current_state在 Rails 控制台中返回然而,当我测试它时出现Client.current_state(Client.last)此错误:

NameError: undefined local variable or method 'state_changes for #<Class:0x0000000685eb88>但是Client.last.state_changes在控制台中运行时它工作正常。

我的客户.rb

class Client < ActiveRecord::Base
  has_and_belongs_to_many               :users
  belongs_to                            :industry
  belongs_to                            :account
  has_many                              :contacts
  has_many                              :state_changes
  belongs_to                            :head,          class_name: "Client"
  has_many                              :branches,      class_name: "Client", foreign_key: "head_id"
  has_many                              :meetings,      through: :contacts
  has_many                              :sales,         through: :meetings

  scope :prospects, -> (client) { where(Client.current_state(client): State.PROSPECT_STATE) }

  def self.has_at_least_one_sale? (client)
    return client.sales.empty?
  end

  def self.has_account_number? (client)
    return client.account_number.present?
  end

  def self.current_state (client)
    state_changes.last.to_state
  end
end
Run Code Online (Sandbox Code Playgroud)

state_change.rb

class StateChange < ActiveRecord::Base
  belongs_to :client
  belongs_to :from_state,   class_name: "State", foreign_key: :to_state_id
  belongs_to :to_state,     class_name: "State", foreign_key: :from_state_id
end
Run Code Online (Sandbox Code Playgroud)

状态文件

class State < ActiveRecord::Base
  has_many :from_states,    class_name: "StateChange", foreign_key: :to_state_id
  has_many :to_states,      class_name: "StateChange", foreign_key: :from_state_id

  def self.PROSPECT_STATE
    return State.find_by name: 'Prospect'
  end

  def self.CLIENT_STATE
    return State.find_by name: 'Client'
  end

  def self.SUSPECT_STATE
    return State.find_by name: 'Suspect'
  end
end
Run Code Online (Sandbox Code Playgroud)

我还收到有关我在 client.rb 中定义的范围的语法错误。我遵循了ActiveRecord指南,但他们没有解释如何在实际范围查询中使用链式方法。

Ing*_*ers 5

您收到错误的原因NameError: undefined local variable or method 'state_changes for #<Class:0x0000000685eb88>是因为您定义current_state为类方法并将客户端作为参数传递。这就是为什么state_changes在类而不是实例上调用的原因。在这种情况下,您需要使用客户端来获取state_changes.

def self.current_state (client)
  client.state_changes.last.to_state
end
Run Code Online (Sandbox Code Playgroud)

范围也意味着只是链接查询逻辑。我不确定是否可以仅使用查询来获得您想要的结果。我希望我正确理解了你的逻辑。或者,您可以使用类方法。

def self.prospects (client)
  Client.all.select { |c| c.current_state(c) == State.PROSPECT_STATE }
end
Run Code Online (Sandbox Code Playgroud)

正如所指出的那样???????在评论中,也许您还想将方法更改为实例方法,在这种情况下,阅读他链接的资源将非常有帮助。

根据评论更新:

我认为你真正想要的是使用这样的实例方法current_state

def current_state
  state_changes.last.to_state
end
Run Code Online (Sandbox Code Playgroud)

然后你可以得到这样的前景:

def self.prospects
  Client.all.select { |c| c.current_state == State.PROSPECT_STATE }
end
Run Code Online (Sandbox Code Playgroud)