Tôi đang cố chỉnh sửa/cập nhật bản ghi mô hình bằng simple_form, nhưng biểu mẫu sẽ không trực tiếp thay đổi trường mô hình. Thay vào đó, tôi cung cấp một vài trường check_box_tag cho biết cập nhật những trường nào cần thay đổi. Do đó, cập nhật không nhận được một tham số [: device] băm mà tôi có thể sử dụng để cập nhật các thuộc tính. Tôi đang cố gắng để tạo ra băm này, nhưng tôi nhận được ForbiddenAttributesError khi tôi phát hành @ device.update_attributes (params [: device]).ActiveModel :: ForbiddenAttributesError sử dụng update_attributes đã tạo tham số băm bản thân mình
Tôi tin rằng danh sách tham số mạnh của tôi là chính xác. Nếu tôi cho phép một trường mô hình (tên) được xử lý trong chế độ xem chỉnh sửa, tôi nhận được các tham số được mong đợi [: device] và mọi thứ hoạt động. Nếu tôi vô hiệu hóa trường đó, bởi vì tôi không muốn nó bị thay đổi, thì tôi cần phải tự tạo bản băm đó và tôi nhận được lỗi. Khi tôi nhìn vào băm tôi tạo ra, nó trông với tôi tương đương với cái băm được xem. Tôi không hiểu tại sao nó thất bại.
Môi trường là Ruby 2.0.0, Rails 4.1 trên Windows 8.1 với RubyMine 6.3.
Các hình thức là: < ... cần định dạng đúng một lần làm việc ...>
<%= simple_form_for @device do |f| %>
<legend><%= controller.action_name.capitalize %> Device:</legend>
<%= f.input :name, disabled: true %>
<%= check_box_tag(:is_admin, 0, @device.admin?) %>
<%= label_tag(:is_admin, "Make admin?") %>
<%= check_box_tag(:chg_pwd) %>
<%= label_tag(:chg_pwd, "Change password?") %>
<%= f.button :submit %>
<% end %>
Các params [: thiết bị] mà tôi nhận được khi tôi đã gửi f.input: tên, khuyết tật: false và cho phép chế độ xem tạo tham số [: device] là:
ActionController::Parameters (3 element(s))
"{"name"=>"D105", "password"=>"D105Dvgr", "password_confirmation"=>"D105Dvgr"}"
Và, mọi thứ đều hoạt động.
Các params [: thiết bị] mà tôi tạo ra là:
ActionController::Parameters (3 element(s))
"{"name"=>"D106", "password"=>"D106VdAd", "password_confirmation"=>"D106VdAd"}"
Và, tôi nhận Forbidden Thuộc tính Lỗi, mặc dù tôi thấy không có sự khác biệt giữa hai người.
Bản cập nhật là: < ... Mã cần refactored, một khi nó được làm việc ...>
class DevicesController < ApplicationController
before_filter :authenticate_device!
... other methods removed here ...
def edit
@device = Device.find(params[:id])
# my_page = render_to_string controller: 'devices', action: 'edit', layout: "application"
end
def update
authorize! :update, @device, :message => 'Not authorized as an administrator.'
@device = Device.find(params[:id])
pwd_msg = ""
if params[:chg_pwd]
pwd_gen = @device.device + SecureRandom.urlsafe_base64(15).tr('lIO0=_\-', 'sxyzEUM').first(4)
params[:device] = {name: @device.name} if params[:device].nil?
params[:device][:password] = pwd_gen
params[:device][:password_confirmation] = pwd_gen
pwd_msg = ", new password is #{pwd_gen}"
end
if @device.update_attributes(params[:device])
params[:is_admin] ? @device.add_role(:admin) : @device.remove_role(:admin)
flash[:notice] = ["Device updated" + pwd_msg]
redirect_to devices_path
else
@device.errors.messages.each do |key, value|
flash[:alert] = ["Unable to update device"]
@device.errors.messages.each do |key, value|
flash[:alert] << key.to_s.capitalize + " " + value[0]
end
end
redirect_to devices_path
end
end
private
def device_params
params.require(:device).permit(:device, :name, :email, :password, :password_confirmation, :encrypted_password, :salt, :role_ids, :is_admin, :chg_pwd) # TODO minimize when update is working
end
end
mô hình
là:class Device < ActiveRecord::Base
rolify
devise :database_authenticatable, :rememberable, :trackable, :validatable
validates :device,
presence: true,
length: {minimum: 4 },
uniqueness: {case_sensitive: false }
validates :name,
presence: true
def remember_me
true unless self.admin?
end
def admin
self.add_role :admin
end
def not_admin
self.remove_role :admin
end
def admin?
self.has_role? :admin
end
def device?
self.has_role? :device
end
def vip?
self.has_role? :vip
end
def login=(login)
@login = login
end
def login
@login || self.device || self.email
end
def self.find_first_by_auth_conditions(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login) # Note one equal sign. Strange but true.
where(conditions).where(["lower(device) = :value OR lower(email) = :value", { :value => login.downcase }]).first
else
where(conditions).first
end
end
end
THÔNG TIN MỚI: Tôi lơ là cung cấp thông tin Tôi có trong ApplicationController. sửa chữa này từ Anton Trapp xử lý các thông số mạnh mẽ đối với đá quý mà chưa được đầy đủ Rails 4 tương thích:
before_filter do
resource = controller_name.singularize.to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
Tôi đã tìm thấy rằng việc sử dụng các giải pháp đề xuất của:
@device.update_attributes(device_params)
không hoạt động nếu một mô hình trường được cập nhật. Kết quả là "param not found: device". Nó hoạt động nếu không có trường mô hình nào được cập nhật. Vì vậy, toàn bộ vấn đề đặt ra câu hỏi về những gì thực sự sai.
Được rồi, thay đổi này có ý nghĩa tổng thể và hoạt động. Tôi vẫn tự hỏi, mặc dù, tại sao nó làm việc theo cách nó là khi một lĩnh vực mô hình đã được tham gia? Bạn có biết rằng? Cảm ơn ... –
'tại sao nó làm việc theo cách nó là khi một lĩnh vực mô hình đã được tham gia?' Có nghĩa là? Trường mô hình nào? Bạn có nghĩa là mã này làm việc trong mọi trường hợp? –
Trong chế độ xem chỉnh sửa, nếu tôi sử dụng "f.input: name, disabled: false", thì thông số [: device] được gửi đến hành động cập nhật với thông số [: davice] [: name] được đặt. Trong trường hợp đó, hành động cập nhật hoạt động như tôi đã làm. Nếu, thay vào đó, tôi sử dụng "f.input: name, disabled: true", để trường name không thể thay đổi, hơn params [: device] là nil. Để update_attributes, tôi đã xây dựng params [: device] như được hiển thị. Cả hai băm đều tương đương nhau. Nhưng, tôi đã nhận được ForbiddenAttributeError trên băm tôi đã xây dựng mặc dù cái mà khung nhìn sửa được xây dựng cho tôi làm việc bằng cách sử dụng @ device.update_attributes (params [: device]). –