2012-04-23 14 views
1

のために作成します。私はstateのための新しいオブジェクトを作成するときNoMethodErrorは、私は次のようしているRailsの3.1を使用して未定義のメソッド `update_column」

# state.rb 
class State < ActiveRecord::Base 
    belongs_to :country, :touch => true 

    after_save :count_total_states 

    private 

    def count_total_states 
    total_states = State.where(:country_id => self.country_id).count 
    Country.where(:id => self.country_id).update_column(:state, total_states) 
    end 
end 

# states_controller.rb 
class StatesController < ApplicationController 
    def create 
    @country = Country.find(params[:country_id]) 
    @state = @country.states.build(params[:state]) 
    @state.position = State.where(:country_id => @country.id).maximum(:position).to_i + 1 
    @state.save 
    end 
end 

、次のエラーが表示さ:

NoMethodError in StatesController#create 

undefined method `update_column' for #<ActiveRecord::Relation:0x1074b0e58> 

コントローラに戻る方法は?お知らせ下さい。

ありがとうございました。

Country.where(:id => self.country_id) 

ActiveRecord::Relationオブジェクトではなく、国を返します。これはので

答えて

3

このエラーがあります。おそらく、代わりにこれらの2つのいずれかを実行する必要があります。それはあなたが本当に欲しいものを行いますので、私は最初のオプションをお勧めしますしかし

Country.find(self.country_id).update_column(:state, total_states) 

または

Country.where(:id => self.country_id).first.update_column(:state, total_states) 

は、IDによってレコードを検索します。主キーがどこかにある場合、あなたの目的は正確な一致を1つだけ返すことです。そのIDを知っているので、直接取得する必要があります。


注:update_columnは、すべての検証をスキップして、私はまた、update_attribute代わりのupdate_columnをお勧めします。あなたが本当にできない限り、検証することは良い考えです。

あなたが使用している動作は、実際には "カウンタキャッシュ"と呼ばれる標準的なRailsの練習にカプセル化されています。目標を達成するためのより良い方法のデモンストレーションについては、blog postRailscastを参照してください。 @Andrew iが適切にここでコードが念のsnipetである(ここで使用して)私の記録を更新できるようにするために、「第一」を追加する必要がありましたmetionedとして

+0

感謝。私はオブジェクトを返すべきだと思った? 「国ではない」とはどういう意味ですか?とにかく、ユーザーに動的に状態を追加/削除させるので、私は 'カウンタキャッシュ 'を使うことができません。 – Victor

+1

これはオブジェクトを返します。ルビのすべてがオブジェクトです。カントリオブジェクトの代わりにActiveRecord :: Relationオブジェクトを返すだけです。カウンタキャッシュは、ユーザーがページ/ dbと動的にやりとりすることで動作します。私は常にアプリケーションで使用します。 railscastとブログ記事をチェックしてください。これは、Code SchoolコースのRailsベストプラクティスでもカバーされています。 – Andrew

0

[ルビー・シナトラ]

私ビュー(あなたがこれらのフォームの値を見ることができます)

... 
    <form action="/device/<%= model.id %>/set-port-value" method="POST"> 
     <input name="number" type="hidden" value="27"/> 
     <input name="value" type="hidden" value="11"/> 
     <input type="submit" value="POST" /> 
    </form> 
    ... 

私のコントローラ

post '/device/:device_id/set-port-value' do 
    # Updating one record: 
    Port.where(number: params[:number]).first.update_column(:value, params[:value]) 

    @models = Port.all 
    erb :'port/all' 
end 
関連する問題