2011-12-28 12 views
2

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

次のように私は取得していますエラーは次のとおりです。

ruby-1.9.3-p0 :005 > User.new :username => "johnsmith", :email => "[email protected]", :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 

答えて

1

あなたは何をしようとしているのか、このmass_assignment_authorizerの目的は何かを完全には確信していません。大量割り当てを防ぐより簡単な方法があるようです。つまり、私は最後のcouple paragraphs of the railscastを読みました。そして、この初期化子をいったん取得すると、オブジェクトの作成時に初期化子に引数を渡すことができないように見えます。可能であれば、属性を設定しませんでした。

コントローラでは、作成可能なオプションを作成アクションにも適用する必要があります。このように適用すればうまくいかないでしょう。

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

これがうまくいかない理由は、時間によって我々は手遅れにアクセスしてきたように、質量割り当てが新しいコールで起こるということです。私たちは、新しい記事の作成を属性の割り当てから分け、呼び出しを2つの間でアクセス可能にする必要があります。

あなたのモデルのいずれかの属性を設定するために、今あなたが最初のように、あなたがしたい属性を割り当てる手動で、その後、クラスの: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 => "[email protected]", :password => "changethis") 

あなたが権限に基づいてアクセス持っている必要がありますどのように多くの属性に応じて、このモジュールをスキップしたほうが良いかもしれません。 1つまたは2つのモデルの属性がほんのわずかな場合は、独自のメソッドとattr_accessibleを使って手動でこの機能を実装するほうがよいでしょう。 this article about ruby accessorsを読んで、おそらくこのプラグインなしで希望の結果を得ることができるかどうか試してみてください。

+0

私が達成しようとしている唯一のことは、特定の属性をアクセス許可に応じてアクセス可能にすることです。 A.k.a.オブジェクトを所有している場合、または管理者の場合 –

+0

レールキャストを見て説明を読み返した後、私はそれについて私の意見を変更しました。私はそれが賢明な修正だと思う。それは、レールスキャストが古くて、レール3.1と互換性がないように見えるということです。 [私は使用しているレールのバージョンのActiveRecordのためのattr_accessibleのドキュメントを読む](http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html#method-i-attr_accessible)。ロールごとにアクセス可能な属性を定義できるようになり、使用しているモジュールが不要になりました。 – Batkins