bar*_*e.m 3 ruby activerecord scope ruby-on-rails
所以我对 Rails 还很陌生,ActiveRecord我需要一个范围来在Client实体之间进行过滤。基本上范围应该返回Client客户端当前状态等于某个状态对象的所有记录。
这是通过获取客户端的上一次计算state_change,然后拉着那个state_change的from_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指南,但他们没有解释如何在实际范围查询中使用链式方法。
您收到错误的原因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)
| 归档时间: |
|
| 查看次数: |
3962 次 |
| 最近记录: |