0

これは簡単なサインアップ アプリケーションです

schema.rb

create_table "users", :force => true do |t|
t.string   "email"
t.string   "password_hash"
t.string   "password_salt"
t.datetime "created_at",    :null => false
t.datetime "updated_at",    :null => false

ユーザー.rb

attr_accessible :email, :password, :password_confirmation
attr_accessor :password
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email
.
.
.

attr_accessible と attr_accessor の両方でパスワードを使用するのはなぜですか?

Rails コンソールで attr_accessor :password を削除すると、実行時にエラーが発生しました。

user = User.new
user.password # => no method error

しかし、私がこれを実行すると:

user = User.new
user.email # => nil

これは、attr_accessor に追加せずに user.email が機能することを意味します。

また、これは機能しています:

user = User.new
user.password_confirmation # => nil

しかし、私が削除したとき:

validates_confirmation_of :password

動作しません。なぜですか??。

4

1 に答える 1

8

attr_accessorattr_accessibleは、ほぼ同じスペルにもかかわらず、まったく異なるメソッドです。

attr_accessor、クラスのインスタンスの getter メソッドと setter メソッドを定義するネイティブ Ruby メソッド:

class User
  attr_accessor :password
end

u = User.new
u.password = "secret"
u.password # => "secret"

attr_accessibleは Rails によってもたらされたメソッドであり、モデルの既存の属性を「ホワイトリストに登録」するためのものです。attr_accessibleで列挙された属性は、後でモデル属性の一括割り当てによって変更できます (他の属性はブラックリストに登録され、変更できません)。

class Account < ActiveRecord::Base
  # First, you define 2 attributes: "password" and "created_at"
  attr_accessor :password
  attr_accessor :created_at

  # Now you say that you want "password" attribute
  # to be changeable via mass-assignment, while making
  # "created_at" to be non-changeable via mass-assignment
  attr_accessible :password
end

a = Account.new

# Perform mass-assignment (which is usually done when you update
# your model using the attributes submitted via a web form)
a.update_attributes(:password => "secret", :created_at => Time.now)

a.password # => "secret"
# "password" is changed

a.created_at # => nil
# "created_at" remains not changed

attr_accessibleを使用して、「部外者」によるモデルの一部の属性の干渉を防ぎます (たとえば、「Account.superadmin」属性を単純なフォーム送信によって変更可能にすると、セキュリティ上の問題が発生する可能性があります)。

「ホワイトリスト/ブラックリスト」ステータスに関係なく、属性を個別に変更できることに注意してください。

a.created_at = Time.now

a.created_at # => 2012-09-16 10:03:14
于 2012-09-16T06:09:51.383 に答える