2

rails-cast #237によると、動的属性は簡単に実装できるはずでした。Railsコンソールでオブジェクトを作成しようとすると、いくつかのエラーが発生しました。お知らせ下さい。

私が得ているエラーは次のとおりです。

ruby-1.9.3-p0 :005 > User.new :username => "johnsmith", :email => "johnsmith@gmail.com", :password => "changethis"
ArgumentError: wrong number of arguments (1 for 0)
    from /Volumes/Terra-Nova/jwaldrip/Sites/theirksome/config/initializers/accessible_attributes.rb:6:in `mass_assignment_authorizer'
    from /Volumes/Terra-Nova/jwaldrip/.rvm/gems/ruby-1.9.3-p0/gems/activemodel-3.1.3/lib/active_model/mass_assignment_security.rb:209:in `sanitize_for_mass_assignment'
    from /Volumes/Terra-Nova/jwaldrip/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.1.3/lib/active_record/base.rb:1744:in `assign_attributes'
    from /Volumes/Terra-Nova/jwaldrip/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.1.3/lib/active_record/base.rb:1567:in `initialize'
    from (irb):5:in `new'
    from (irb):5
    from /Volumes/Terra-Nova/jwaldrip/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.1.3/lib/rails/commands/console.rb:45:in `start'
    from /Volumes/Terra-Nova/jwaldrip/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.1.3/lib/rails/commands/console.rb:8:in `start'
    from /Volumes/Terra-Nova/jwaldrip/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.1.3/lib/rails/commands.rb:40:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

/models/user.rb :

class User < ActiveRecord::Base

    # Attributes
    attr_accessible :username, :email, :password, :password_confirmation, :is_admin
    attr_accessor :password

    # Callbacks
    before_save :encrypt_password

    # Relationships
    has_many :irks

    # Validation
    validates_confirmation_of :password
    validates_presence_of :password, on: :create
    validates :password, presence: true, length: { in: 3..20 }

    validates :username, presence: true, uniqueness: true, length: { in: 3..20 }
    validates :email, presence: true, email: true, uniqueness: true

    # User Authentication
    def self.authenticate(email, password)
        user = find_by_email(email)
        if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
            user
        else
            nil
        end
    end

    # Password Encryption
    def encrypt_password
        if password.present?
            self.password_salt = BCrypt::Engine.generate_salt
            self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
        end
    end
end

/config/initializers/accessible_attributes.rb :

class ActiveRecord::Base
    attr_accessible
    attr_accessor :accessible

    private

    def mass_assignment_authorizer
        if accessible == :all
            self.class.protected_attributes
        else
            super + (accessible || [])
        end
    end
end
4

1 に答える 1

1

あなたがやろうとしていること、またはこの mass_assignment_authorizer の目的が何であるかが正確にはわかりません。大量割り当てから保護する簡単な方法があるようです。そうは言っても、 railscastの最後の数段落を読んだところ、このイニシャライザを取得すると、オブジェクトの作成時にイニシャライザに引数を渡すことができないように見えます。できたとしても、属性を設定しません...

コントローラーでは、accessible オプションを create アクションに適用する必要もあります。このように適用するだけでは機能しません。

@article = Article.new(params[:article])
@article.accessible = :all if admin?

これが機能しない理由は、大量の割り当てが新しい呼び出しで発生するため、アクセス可能に設定するまでには手遅れです。新しい Article の作成とその属性の割り当てを分離し、accessible の呼び出しを 2 つの間に挿入する必要があります。

したがって、モデルの1つの属性を設定するには、最初にモデルを作成し、次に:allクラスにアクセス可能に設定してから、次のように手動で必要な属性を割り当てる必要があるように見えます:

u = User.create
u.accessible = :all if current_user.is_admin? # or whatever the conditional is for the admin user
u.update_attributes(:username => "johnsmith", :email => "johnsmith@gmail.com", :password => "changethis")

アクセス許可に基づいてアクセスできるようにする必要がある属性の数によっては、このモジュールをスキップしたほうがよい場合があります。1 つまたは 2 つのモデルの少数の属性のみの場合は、独自のメソッドと attr_accessible を使用してこの機能を手動で実装する方がよい場合があります。Ruby アクセサーに関するこの記事を読んで、このプラグインがなくても目的の結果が得られるかどうかを確認してみてください。

于 2011-12-28T22:11:59.650 に答える