[英]Dynamic attr_accessible in rails
根據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
不能完全確定您要執行的操作或此mass_assignment_authorizer的用途是什么。 似乎有更簡單的方法可以防止大規模分配。 話雖如此,我閱讀了railscast的最后幾段 ,似乎您有了這個初始化程序后,創建對象時就無法將任何參數傳遞給初始化程序。 即使可以,也不會設置屬性...
在控制器中,我們還需要將可訪問選項應用於create動作。 如果我們只是像這樣應用它,它將無法正常工作。
@article = Article.new(params[:article])
@article.accessible = :all if admin?
之所以不起作用,是因為新呼叫中發生了批量分配,因此在我們設置可訪問性時為時已晚。 我們需要將創建新文章與分配其屬性分開,並將調用滑動到兩者之間。
因此,在我看來,為了現在為您的一個模型設置屬性,您首先需要創建它,然后在類上將accessibility設置為: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")
根據需要基於權限需要訪問的屬性數量,最好跳過此模塊,因為它需要執行一些額外的工作。 如果在一個或兩個模型上只有幾個屬性,那么最好使用自己的方法和attr_accessible手動實現此功能。 嘗試閱讀有關紅寶石訪問器的文章 ,看看是否可以在沒有此插件的情況下獲得所需的結果?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.