web-dev-qa-db-ja.com

同じフィールドでattr_accessorとattr_accessibleを使用する

次のコードでバックグラウンドで何が起こりますか?

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end

ヒント:クラスをインスタンス化するときに、データベースに永続化されますか?なぜまたはなぜそうではないのですか?

21
Magne

迅速な回答をありがとうございました!あなたの答えを組み合わせると、このパズルを理解するために必要なピースが得られたと思います。

(関連する問題で、「オブジェクトは#inspectをサポートしていません」や「nil:NilClassの未定義のメソッド 'キー'」などの多くのnilエラーが発生していました。att_accessorフィールドを削除することで、これを解決できました。完全に。)

この特定のケースを実験することによって、これは私が見つけたものです:

実際には、:nameフィールドはデータベースに永続化されません。

user = User.new(:name=>"somename")

オブジェクトに属性を設定するだけで、:name列をデータベースに永続化しません。次のような「Railsコンソール」の出力は次のようになります。

> user
=> <User id: nil, created_at: nil, updated_at: nil>
> user.save
=> true
> user
=> <User id:1, created_at: 2011-01-19 12:37:21, updated_at: 2011-01-19 12:37:21>

これは、* attr_accessorによって作成されたセッターがActiveRecordのセッター*(データベースの永続性を処理する)をオーバーライドするためだと思います。ただし、次のように、オブジェクトの:nameフィールドから値を取得することはできます。

> user.name
=> "somename"

したがって、結論として、フィールドでattr_accessorを使用すると、フィールドがデータベースに永続化されない可能性があることを学びました。 attr_accessibleは、外部からアクセスできるはずのデータベース内のフィールドを記述していると思いましたが、この場合は違いがないようです。

4
Magne

attr_accessorはRubyコードであり、データベースに列がないが、フォームにフィールドを表示したい場合に使用されます。これを許可する唯一の方法はattr_accessor :fieldname必要に応じて、ビューまたはモデルでこのフィールドを使用できますが、ほとんどの場合、ビューで使用できます。

attr_accessibleを使用すると、上記で説明したように、一括割り当てを許可するすべての列を一覧表示できます。これの反対はattr_protectedです。これは、このフィールドに誰にも一括割り当てを許可したくないことを意味します。多くの場合、それはデータベース内のフィールドになり、だれもいじくり回してほしくないでしょう。ステータスフィールドなど。

70
pjammer

ほとんどの場合、フィールドがデータベースのusersテーブルの列である場合は、attr_accessorを使用する必要はありません。 ActiveRecordはあなたのためにそれを理解します。

attr_accessibleを使用すると、一括割当を介してフィールドを割り当てることができます(たとえば、update_attributesを使用)。これはセキュリティの目的に適しています。 MassAssignmentSecurity APIドキュメント からの詳細情報。

5
Andy Lindeman

ActiveRecordを継承するため、saveメソッドを呼び出したときに保持されます(ただし、インスタンス化されたときは保持されません)。

そのモデルの属性がない場合は、ActiveRecordがデータベースに新しい行を保存するだけだと思います(つまり、オブジェクトには永続化されたidのみが含まれます)。後でUserモデルに属性を追加する可能性があるため、これは理にかなっています。永続化されたインスタンスは引き続き取得可能である必要があります。

1
David Sulc