I have a form that users enter data in, with a button to save the data. The form also has buttons to send the user to other forms to enter more info.
<%= form_with(model: [order_header], local: true) do |f| %>
<%= render "shared/errors", object: order_header %>
<%= f.hidden_field(:customer_id, value: #customer.id) %>
<%= f.label :status %>
<%= f.select(:status, [['Quote', 1], ['Order', 3], ['Invoice', 5]]) %>
<%= f.label :customer_purchase_order %>
<%= f.text_field :customer_po %>
<h4>Lines</h4>
<table cellpadding=10>
<% #orderlines = order_header.order_lines %>
<% #orderlines.each do |line| %>
<tr>
<td><%= line.line_type %></td>
<td><%= line.description %></td>
<td><%= link_to 'Edit', edit_design_item_path(line.design_item_number), class: "inline_button" %></td>
<% end %>
</tr>
</table>
<section class="button-bar">
<%= f.submit "Save", class: "button" %>
</section>
<% end %>
If the user hits an 'Edit' button, before hitting the 'Save' button, the data entered on the main form is lost. Is there a way to automatically save the data on the main form before calling the other form via the edit button?
I am trying to create a button in View that will create a new record and display in another controller and then display that View.
However I get this error when I click that button.
ActionController::ParameterMissing in JobHeadersController#create
param is missing or the value is empty: job_header
# Never trust parameters from the scary internet, only allow the white list through.
def job_header_params
params.require(:job_header).permit(:company_id, :customer_id, :name, :del_address1, :del_address2, :del_address3, :del_address4, :del_postcode, :tel, :created_by)
end
end
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"BLAHBLAHBLAHg==",
"company_id"=>"2",
"customer_id"=>"1",
"name"=>"Nash Labs",
"del_address1"=>"23 Taylor Road",
"del_address2"=>"Odsal",
"del_address3"=>"Bradford",
"del_address4"=>"West Yorkshire",
"del_postcode"=>"BD6 1BH",
"tel"=>"07522189605",
"created_by"=>"2",
"button"=>""}
My View code is
<%= form_tag({controller: "job_headers", action: "create"}, method: "post") %>
<% #other_assets.each do |assets| %>
<tr>
<td><%= check_box_tag 'selected_assets[]', assets.id%></td>
<td><%= assets.service_type %></td>
<td><%= assets.asset_type %></td>
<td><%= assets.make %></td>
<td><%= assets.model %></td>
<td><%= assets.serial_no %></td>
<td><%= format_date(assets.date_next) %></td>
<td><%= link_to "Notes", customer_asset_service_register_path, :id => 'notesModal', "data-toggle" => "modal", 'data-target' => '.bs-example-modal-lg' %></td>
</tr>
<% end %>
</table>
</div>
<%= hidden_field_tag :company_id, #customer.company_id %>
<%= hidden_field_tag :customer_id, #customer.id %>
<%= hidden_field_tag :name, #customer.name %>
<% if #customer.del_address1.blank? %>
<%= hidden_field_tag :del_address1, #customer.address1 %>
<% else %>
<%= hidden_field_tag :del_address1, #customer.del_address1 %>
<% end %>
<% if #customer.del_address1.blank? %>
<%= hidden_field_tag :del_address2, #customer.address2 %>
<% else %>
<%= hidden_field_tag :del_address2, #customer.del_address2 %>
<% end %>
<% if #customer.del_address1.blank? %>
<%= hidden_field_tag :del_address3, #customer.address3 %>
<% else %>
<%= hidden_field_tag :del_address3, #customer.del_address3 %>
<% end %>
<% if #customer.del_address1.blank? %>
<%= hidden_field_tag :del_address4, #customer.address4 %>
<% else %>
<%= hidden_field_tag :del_address4, #customer.del_address4 %>
<% end %>
<% if #customer.del_address1.blank? %>
<%= hidden_field_tag :del_postcode, #customer.postcode %>
<% else %>
<%= hidden_field_tag :del_postcode, #customer.del_postcode %>
<% end %>
<%= hidden_field_tag :tel, #customer.tel %>
<%= hidden_field_tag :created_by, current_user.id %>
<div class="box-tools pull-right">
<%= button_tag(type: "submit", class: "btn btn-primary pull_right") do %>
<i class='fa fa-calendar'></i> Create Job
<% end %>
<% end %>
If I am reading the error right it is expecting the param "job_header" and it is null however, this is to create a new job_header record and so I can't pass that param?
If anyone also knows how I Can put a tick box against my table rows so that the selected #other_asset id's get passed to a param as an array please also let me know. It will save me lots of googling.
Thanks in advance
ActionController::ParameterMissing in JobHeadersController#create
param is missing or the value is empty: job_header
You are using a form_tag to submit the data, so there won't be any key(model instance) to which the params append. You just need to change
params.require(:job_header).permit(:company_id, :customer_id, :name, :del_address1, :del_address2, :del_address3, :del_address4, :del_postcode, :tel, :created_by)
to
params.permit(:company_id, :customer_id, :name, :del_address1, :del_address2, :del_address3, :del_address4, :del_postcode, :tel, :created_by)
Rails way: Use form_for #job_header do |f|
to create a form scoped by #job_header and in job_header_params will be:
{"utf8"=>"✓", "authenticity_token"=>"BLABLABLA",
"job_header": {
"company_id"=>"2",
"customer_id"=>"1",
"name"=>"Nash Labs",
"del_address1"=>"23 Taylor Road",
"del_address2"=>"Odsal",
"del_address3"=>"Bradford",
"del_address4"=>"West Yorkshire",
"del_postcode"=>"BD6 1BH",
"tel"=>"07522189605",
"created_by"=>"2"},
"button"=>""}
The exception is saying that the required node (:job_header) is missing and can find the permitted params (params['job_header'] => nil).
More at https://api.rubyonrails.org/v5.1/classes/ActionView/Helpers/FormHelper.html
Pay attention to these items that you didn't get it:
https://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html
https://guides.rubyonrails.org/form_helpers.html
And if you already have the information for those hidden fields (in #customer), why you send to the view to receive the """same""" information back from it? (The same with " because a user can alter this data with a page inspection and send maliciously code...)
Only fill these attrs on the controller.
In my Ruby on Rails application I have the following form for booking_line view:
<%= form_for #booking_line do |f| %>
<%= f.hidden_field :showing_id %>
<%= image_tag "thor_hammer.jpg",:size => "900x250" %>
<td width="300px"> <br><%= f.label :seat_id, 'Please Select a Seat:' %>
<br><%= f.collection_select :seat_id, free_seats, :id,:seats_available %><br>
</td>
<td width="300px">
<div class="actions">
<%= f.submit %>
</div>
<br>
<%= render "/error_messages", :message_header => "Cannot save: ", :target => #booking_line %>
</td>
<% end %>
But as this is booking_line, what I want to happen is that when the submit button is clicked it creates a booking and a booking_line because in the booking_line table it has the attribute booking_id so that the association is made between the two. How can I achieve this?
you can use url in form_for method..to overwrite individual conventions, such as:
<%= form_for(#post, url: my_custom_path) do |f| %>
...
<% end %>
and then add your own logic at my_custom action to achieve it
I have a button on an index page that links to a new_assignment_path
<% #users.each do |user| %>
<tr>
<td><%= link_to user.name, user %></td>
<td><%= link_to 'Assign to Class', new_assignment_path, :class => 'btn btn-mini' %></td>
</tr>
<% end %>
And I want it so that when you click on it, it takes you to the new_assignment_path, and takes the dropdown select on that pages form.
<%= simple_form_for(#assignment) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :user_id, collection: User.all.collect, as: :select %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
And have the drop down automatically set to the user.id of whatever user the button was inside of.
<%= link_to 'Assign to Project', new_assignment_path(#assignment, :user_id => user.id), :class => 'btn btn-mini' %>
and
<%= link_to 'Assign to Project', new_assignment_path(:user_id => user.id), :class => 'btn btn-mini' %>
And neither of them worked.
What is the best way of doing this?
With your second option try setting the instance variable in the AssignmentsController.
#user_id = params[:user_id]
Then you need to specify the default in the form
<%= f.input :user_id, collection: User.all.collect, selected: #user_id %>
You don't need as: :select with Simple Form.
I am new to rails, I am using the ancestry gem and I am having trouble passing the parent_id via a form.
<% title "Messages" %>
<% for message in #messages %>
<div class="message">
<div class="created_at"><%= message.created_at.strftime("%B %d, %Y") %></div>
<div class="content">
<%= message.content %>
</div>
<div class="actions">
<%= link_to "Reply", new_message_path(:parent_id => message) %> |
<%= link_to "Destroy", message, :confirm => "Are you sure?", :method => :delete %>
</div>
</div>
<% end %>
<%= semantic_form_for #message do |f| %>
<%= f.error_messages %>
<p><%= f.select :content, [['United States','2'],['England','3'],['London','4']] %></p>
<p><%= link_to "Reply", new_message_path(:parent_id => :content) %></p>
<% end %>
I am trying to assign a number (if the user selects 'United States' the number will be '2') to some variable and pass that variable when the user click reply as <%= link_to "Reply", new_message_path(:parent_id => some_variable) %>
You are doing it wrong. Rethink the problem. You probably want to do something like
<%= semantic_form_for #message do |f| %>
<%= f.error_messages %>
<p><%= f.select :parent_id, [['United States','2'],['England','3'],['London','4']] %></p>
<p><%= f.submit "Reply" %></p>
<% end %>
And define needed routes.