2

私は最近これに噛まれました、そしてこれを起こさせるために何が起こっているのかを正確に知ることは役に立つでしょう、それで他の人はこの間違いを避けます。

次のようなスキーマを持つモデルUserがあります。

create_table "users", :force => true do |t|
    t.string   "user_name"
    t.string   "first_name"
    t.string   "last_name"
    t.string   "email"
    t.string   "location"
    t.string   "town"
    t.string   "country"
    t.string   "postcode"
    t.boolean  "newsletter"

クラスuser.rbには、次の3つのメソッド用のattr_accessorがあります。

class User < ActiveRecord::Base

# lots of code

  attr_protected :admin, :active

# relevant accessor methods

  attr_accessor :town, :postcode, :country 

end

次の方法がある場合、ユーザーコントローラーで次のようになります。

def create
    @user = User.new params[:user]
end

このparamsハッシュの内容で新しいユーザーを作成しようとすると:

  --- !map:HashWithIndifferentAccess 
  # other values
  country: United Kingdom
  dob(1i): "1985"
  dob(2i): "9"
  dob(3i): "19"
  town: london

country返されるオブジェクトには、のように、townおよび郵便番号のpostcode値に空の文字列が含まれています。

(rdb:53) y user1
--- !ruby/object:User 
attributes: 
  # lots of attributes that aren't relevant for this example, and are filled in okay
  postcode: 
  country: 
  town: 

attr_accessorメソッドがActiveRecordの既存のアクセサーメソッドを覆い隠していることがわかります。なぜなら、それらを取り出すとすべて正常に機能するため、解決策はかなり簡単です。それらを取り出すだけです。

しかし、ここでが起こっているのでしょうか?

私はここActiveRecordのRailsAPIドキュメントRuby自身のドキュメントattr_accessorを探していますが、ここでどのように問題が発生しているかについてはまだ少しぼんやりしてattr_accessorいます。

他の貧しい魂がこれに反するのを防ぐために光を当てることができる人はいますか?

4

3 に答える 3

8

attr_accessorをクラスに追加すると、そのクラスに2つのメソッド(User#postcodeとUser#postcode =など)が定義されます。

アクセサの名前がモデル属性の名前と等しい場合、物事は壊れます(注意しないと)。モデルに属性を割り当てると、User#postcode =が呼び出され、あなたの場合はそれ以外は何もしません。

@postcode = value

したがって、値はインスタンス変数に格納されるだけで、属性ハッシュには表示されません。

通常のシナリオ(アクセサーなし)では、これはmethod_missingに移動し、最終的には次のようなトリガーになります。

write_attribute(:postcode, value)

そして、それはモデルの属性に表示されます。それが理にかなっていることを願っています。

于 2009-09-19T12:13:45.183 に答える
0

なぜ最初に使用しているの attr_accessor :town, :postcode, :countryですか?Active Recordには、セッター/ゲッターメソッドがあります。その行をドロップするだけで、うまくいくはずです。

于 2009-09-19T12:04:43.970 に答える
0

ActiveRecordモデルで使用attr_accessibleして、属性の一括割り当てを有効にすることができます。attr_accessorゲッター/セッターはモデル属性に対してすでに定義されているため、必要ありません。

于 2009-09-19T12:43:07.240 に答える