2016-07-04 10 views
1

これでレールがかなり新しくなりました。ActiveRecordClientエンティティ間のフィルタリングの必要があります。基本的にスコープは、クライアントの現在の状態が特定の状態オブジェクトと等しいすべてのClientレコードを返す必要があります。メソッドの値を比較したRailsスコープ

これを取得することによって計算され、クライアントのstate_change最後に、その後引っ張っstate_changefrom_stateState目的であること。

NameError: undefined local variable or method 'state_changes for #<Class:0x0000000685eb88>が、コンソールでClient.last.state_changesを実行するときには、正常に動作します:

私は私はこのエラーが出るClient.current_state(Client.last)でそれをテストするとき、レールコンソールでただしcurrent_stateを返すメソッドを定義しています。

マイclient.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 

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 

state.rb

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 

また、私はclient.rbで定義された範囲に関する構文エラーを取得します。私はActiveRecordガイドに従ってきましたが、実際のスコープクエリにチェーンメソッドを持たせる方法は説明していません。

+1

[Rubyのクラスとインスタンスメソッド](http://www.railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/)をお読みになることをお勧めします –

答えて

1

エラー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 

また、スコープはクエリロジックを連鎖させるためのものです。あなたが望む結果を得るためにクエリを使うことが可能かどうかは分かりません。そして、私はあなたのロジックを正しく理解することを願っています。あるいは、クラスメソッドを使用することもできます。

def self.prospects (client) 
    Client.all.select { |c| c.current_state(c) == State.PROSPECT_STATE } 
end 

としては、多分あなたはまた、ちょうど彼がリンクされたリソースを読み込むことは非常に参考になる、その場合には、インスタンスメソッドにメソッドを、変更したい、コメントでЗелёныйによって指摘しました。コメントをもとに

更新:

私はあなたが実際にこのようなcurrent_stateのインスタンスメソッドを使用している何をしたいと思う:

def current_state 
    state_changes.last.to_state 
end 

をそして、あなたはこのような見通しを得ることができます。

def self.prospects 
    Client.all.select { |c| c.current_state == State.PROSPECT_STATE } 
end 
+0

ありがとうあなたはfまたはあなたの答え。なぜself.prospectsのパラメータが必要なのか分かりません。それは、prospect_stateを持つすべてのクライアントを単に返すことです。 –

+0

'Client.all.select {| c | Client.current_state(c)== State.PROSPECT_STATE} 'はうまくいきました。ありがとうございました!そして私はそのリソースを読んだ。 –

+0

あなたのコメントに基づいてアップデートを追加しました。 – IngoAlbers