2012-01-02 7 views
0

モデルのプロパティを更新するコードがあり、save!を呼び出しています。 Rails.logger.infoコールは、モデルが新しい値を持つとモデルが判断したことを示します。しかし、save!呼び出しによって実行されるSQL書き込みは、古い値をデータベースに書き込むことです。Rails 3:object.saveが古い値をデータベースに書き込んでいます

save!を呼び出すと、当初はデータベースに何も書き込んでいませんでした。私はオブジェクトが何らかの理由でその値が変更されたとは考えていないと思っていました。changed?がfalseを返したため、書き込みを強制するために_will_change!通知を使用しました。しかし、今は書き込みをしていますが、古い値を使っています。

これは「rails console」コマンドラインからは発生しません。そこではプロパティを更新できます。changed?がtrueを返し、正常に保存されます。

サーバーログの抜粋は次のとおりです。オブジェクトは、log_ids'1234,5678,1137'だと考えますが、データベース'1234,5678'に書き込みます。

現在のログIDは、[1234 5678]
新しいログIDは、[1234 5678、1137]。 「1234,5678,1137」のlog_idsを、汚れた真実でNewsList 13に書き込む
SQL(2.0ms)UPDATE「news_lists」SET「log_ids」=「1234,5678」、「updated_at」= '2012-01-02 02: 12:17.612283' WHERE( "news_lists" "ID" = 13)

は、問題のオブジェクトプロパティは、オブジェクトの別の種類のいくつかのIDを含む文字列である、log_idsあります。

は、上記の出力を生成するソースコード:

def add_log(new_log) 
    new_ids = get_log_ids 
    Rails.logger.info("current log ids are #{new_ids}") 
    if new_ids.length >= NewsList.MAX_LENGTH 
    new_ids.shift 
    end 
    log_ids_will_change! 
    new_ids.push new_log.id 
    log_ids = new_ids.join "," 
    Rails.logger.info("new log ids are #{new_ids}; writing log_ids of '#{log_ids}' to NewsList #{id} with dirty #{changed?}") 
    save! 
end 
def get_log_ids 
    if log_ids 
    log_ids.split(",").map &:to_i 
    else 
    [] 
    end 
end 

誰もがここで起こっかもしれないものを提案することはできますか?

+0

ActiveRecordの場合、ARがどのように動作するのかによって、「裸の」変数だけでなく、自己からDBプロパティにアクセスする必要はありませんか? –

答えて

3

自分自身をself.log_ids = new_ids.join ","に追加します。そうしないと、db-persisted属性(列)の代わりにローカル変数(namesake)に割り当てられます。

+0

うわー。私はActiveRecordのその特有の奇抜なことにこれまで遭遇したことはなかった。私はそれらの2つの構文の間に全く違いがあるのか​​どうかはわかりませんでしたが、それはそれを修正します。なぜそれは名前空間のローカル変数を作成するのですか? – AlexC

+0

セッターに割り当てるときは、常に明示的に 'self'を追加する必要があります。そうでなければ、インタープリターはローカル変数を作成します。ローカルvarを作成するかセッターを呼び出すかは分かりません。ローカル変数を作成します。スコープ内でその名前のローカル変数が見つからない場合は、そのメソッドを呼び出そうとするので、getterの場合はselfの前に接頭辞を付ける必要がないため、getterの場合とは異なります。 – clyfe

関連する問題