21

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

class User < ActiveRecord::Base

 attr_accessor :name
 attr_accessible :name

end

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

4

4 に答える 4

70

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

attr_accessible を使用すると、上記の andy が回避したように、一括割り当てを許可するすべての列を一覧表示できます。これの反対は attr_protected です。つまり、このフィールドは誰にも一括割り当てを許可したくないということです。それよりも、誰にも弄ばれたくないデータベースのフィールドになる可能性が高くなります。ステータスフィールドなどのように。

于 2011-01-15T18:22:35.710 に答える
5

ほとんどの場合、フィールドがデータベースattr_accessorのテーブルの列である場合は使用する必要はありません。usersActiveRecord が解決します。

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

于 2011-01-15T17:21:17.863 に答える
4

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

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

この特定のケースを試してみると、次のことがわかりました。

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

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

オブジェクトに属性を設定するだけで、:name 列をデータベースに保持しません。次の「rails console」出力のように:

> 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 は、外部からアクセスできるデータベース内のフィールドを記述すると思っていましたが、この場合は違いがないようです。

于 2011-01-19T13:22:44.310 に答える
1

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

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

于 2011-01-15T16:49:23.720 に答える