I currently have a form that builds a vehicle. The vehicle model initially looks like:
class Vehicle < ActiveRecord::Base
attr_accessible :trim_id
belongs_to :trim
end
You will note that there are no make_id
or model_id
columns; these are not required, since a trim belongs to a model, and a model belongs to a make, so they do not need to be stored in the vehicle model.
The problem arises on the vehicle form - I have some linked selects, where I can select a make, then a model, then a trim. When I am creating a new vehicle, the following code works fine:
<%= select("", "", Make.all.collect {|p| [ p.value, p.id ] }, {:prompt => 'Select Make'}, {} %>
<%= f.select("", "", options_for_select([]), {:prompt => 'Select Model'}, {} %>
<%= f.select(:trim_id, options_for_select([]), {:prompt => 'Select Trim'} %>
As you will note, the make and model selects do not have form parameters, and thus are ignored. This works fine, and the vehicle is saved correctly.
The difficulty arises when I want to edit this vehicle; because make and model simply dummy selects to chain to the trim, they are initially set to the default value, not the make and model of the vehicle being edited. As a result I have updated my model to look like:
class Vehicle < ActiveRecord::Base
attr_accessible :trim_id
belongs_to :trim
has_one :model, :through => :trim
has_one :make, :through => :model
end
And updated the form to:
<%= f.select(:make, Make.all.collect {|p| [ p.value, p.id ] }, {:prompt => 'Select Make'}, {} %>
<%= f.select(:model, options_for_select([]), {:prompt => 'Select Model'}, {} %>
<%= f.select(:trim_id, options_for_select([]), {:prompt => 'Select Trim'} %>
But, as would be expected, this results in Can't mass-assign protected attributes: make, model
, since make and model are not attr_accessible (and in any case the make and model columns do not exist).
My question is this: is there a way to ignore these fields when submitting a new vehicle form, but still have them select the correct values when a vehicle is being edited?
Thanks!
EDIT: Per the answer from Beerlington, I have updated my create
action as follows:
def create
@sale = Sale.new
current_ability.attributes_for(:new, Sale).each do |key, value|
@sale.send("#{key}=", value)
end
@sale.update_attributes(params[:sale].except("date"))
authorize! :create, @sale
if @sale.save
redirect_to @sale, :notice => "Successfully created sale."
else
render :action => 'new'
end
end
You will note that I am trying to except "date" here (have also tried :date) - this was to test with a non-nested attribute.
I am finding, however, that date is still being submitted - can anyone assist with the full controller action using Hash#except?
EDIT 2: I have marked Beerlington's answer as correct, as it answered the original question - I have asked a follow-up question here: Excluding nested form fields in controller action with Hash#exclude before mass_assignment error is generated?
The <input type="hidden"> defines a hidden input field. A hidden field lets web developers include data that cannot be seen or modified by users when a form is submitted. A hidden field often stores what database record that needs to be updated when the form is submitted.
Tip: Disabled <input> elements in a form will not be submitted!
The Javascript uses jQuery to change the DOM depending on the selections made. Essentially, depending on the conditions of a field answer, you can bulk turn show/hide other components of the form. For validation purposes, some extra attributes are changed depending on the selection.
To clear an input field after submitting: When the button is clicked, set the input field's value to an empty string. Setting the field's value to an empty string resets the input.
You can remove the keys that aren't needed by using Hash#except:
@vehicle.update_attributes(params[:vehicle].except(:make, :model))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With