Próbuję edytować/zaktualizować rekord modelu za pomocą simple_form, ale formularz nie zmieni bezpośrednio pola modelu. Zamiast tego, oferuję kilka pól check_box_tag, które informują o aktualizacji, które pola wymagają zmiany. W rezultacie aktualizacja nie otrzymuje wartości skrótu [: device], której można użyć do aktualizacji atrybutów. Próbuję utworzyć ten skrót, ale otrzymuję komunikat ForbiddenAttributesError, gdy uruchamiam @ device.update_attributes (parametry [: device]).ActiveModel :: ForbiddenAttributesError przy użyciu update_attributes, które utworzyło mieszanie params ja
Wierzę, że moja lista silnych parametrów jest poprawna. Jeśli zezwalam na przetwarzanie jednego pola modelu (nazwy) w widoku edycji, otrzymuję oczekiwane parametry [: device] hash i wszystko działa. Jeśli wyłączę to pole, ponieważ nie chcę, aby zostało ono zmienione, muszę je utworzyć osobiście i otrzymam błąd. Kiedy patrzę na hasz, który utworzyłem, wygląda na to, że jest to odpowiednik tego, który przeszedł przez widok. Nie rozumiem, dlaczego to się nie udaje.
Środowisko to Ruby 2.0.0, Rails 4.1 w systemie Windows 8.1 z RubyMine 6.3.
Formularz jest: < ... potrzebuje poprawnego formatowania raz praca ...>
<%= 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 %>
params [:], że urządzenie otrzyma Kiedy wysłałem f.input: imię, niepełnosprawnych: false i pozwól widokowi generować parametry [: urządzenie] to:
I wszystko działa.
params [:] Urządzenie, które tworzę jest:
ActionController::Parameters (3 element(s))
"{"name"=>"D106", "password"=>"D106VdAd", "password_confirmation"=>"D106VdAd"}"
A ja otrzymać Zakazane atrybutu błąd, chociaż nie widzę różnicy między nimi.
Aktualizacja jest: < ... Kod musi refactored, raz to działa ...>
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
Model jest:
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
NOWE INFORMACJE: I zaniedbane dostarczenie informacji Mam w ApplicationController. Ta poprawka Anton Trapp obsługuje silne parametry klejnotów, które nie są jeszcze w pełni kompatybilny Szyny 4:
before_filter do
resource = controller_name.singularize.to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
I odkryli, że za pomocą proponowanego rozwiązanie:
@device.update_attributes(device_params)
nie działa, jeśli model pole jest aktualizowane. Rezultatem jest "nie znaleziono parametru: urządzenie". Działa, jeśli żadne pole modelu nie jest aktualizowane. Cała ta kwestia nasuwa pytanie o to, co jest naprawdę złe.
Okay, zmiana ma sens i działa. Nadal zastanawiam się, dlaczego działało to tak, jak było, gdy chodziło o pole modelowe? Wiesz to? Dzięki ... –
"dlaczego zadziałało tak, jak było, gdy zaangażowane było pole modelowe?" Oznacza? Które pole modelu? Czy masz na myśli, że ten sam kod działał w każdym przypadku? –
W widoku edycji, jeśli użyję "f.input: name, disabled: false", wówczas parametry [: device] zostaną wysłane do akcji aktualizacji z ustawieniem parametrów params: set [: davice] [: name]. W takim przypadku akcja aktualizacji działała tak jak ją miałem. Jeśli zamiast tego użyję "f.input: name, disabled: true", tak, że pola nazwy nie można zmienić, niż parametry [: device] is nil. Aby zaktualizować atrybuty, zbudowałem parametry [: urządzenie], jak pokazano. Oba skróty są równoważne. Ale otrzymałem ForbiddenAttributeError na haszach, które zbudowałem, mimo że ten, który został stworzony dla mnie przez edycję, działał przy użyciu @ device.update_attributes (parametry [: device]). –