I'm having issues with a form in my Rails 6 application.
I have a remote form which enters new data into the database via a JSON request, which works but only with one parameter. This is the form:
<%= form_with(method: :post, remote: true, model: Meal.new, url: meals_path, class: "editMealsForm", data: { type: "json" }) do |f| %>
<div class="field">
<%= f.label :description, 'Beschreibung' %><br>
<%= f.text_area :description, rows: "4", placeholder: "Noch keine Mahlzeit für diesen Tag vorhanden, bitte eintragen!", class: "form-control" %>
</div>
<div class="field">
<%= f.label :allergene_ids_add, 'Allergene auswählen', class: "card-text" %><br>
<%= select_tag :allergene_ids_add, options_from_collection_for_select(#allergenes, :id, :name), multiple: true, class: "selectpicker", data: { style: "btn-success", width: "fit", live_search: "true", size: "5", title: "Allergien wählen" } %>
</div>
<% f.hidden_field :day, :value => local_assigns[:mealDay] %>
<% f.hidden_field :tip, :value => "Vollkost" %>
<%= f.submit "Speichern", class: "btn btn-primary mt-2 btn-block" %>
<% end %>
And these are my permitted parameters:
def meal_params
params.require(:meal).permit(:day, :tip, :description, allergene_ids_add: [])
end
And this is my controller action:
def create
#meal = Meal.new(meal_params)
byebug
if #meal.save
if params[:allergene_ids_add].present?
#allergenes_to_add = Allergene.find(params[:allergene_ids_add])
#allergenes_to_add.each do |allergene|
#meal.allergenes << allergene
end
end
respond_to do |format|
format.html { redirect_to meals_path }
format.json { render json: #meal }
end
end
end
The problem is, that if I hit the create action, just the description parameter is permitted, the other ones are just "ignored", so if I fire the submit button I get the following output in the console if I hit my byebug breakpoint:
And if I look at the params:
<ActionController::Parameters {"authenticity_token"=>"derBZeirq0bwr/FWoYRr97qUZ5p66vQc+uT+UMf5xjXXTSFEp+XOepJtGrckguGh+skWXTZ9ibHWfFTt3p80Cg==", "meal"=><ActionController::Parameters {"description"=>"test"} permitted: false>, "commit"=>"Speichern", "controller"=>"meals", "action"=>"create"} permitted: false>
Or just at the meal params:
<ActionController::Parameters {"description"=>"test"} permitted: true>
If I run #meal.valid? it returns true, so I don't see where the issue is.
Also if I check the values for the hidden fields in the form, they are filled and not nil.
So why does this one parameter work, but the rest just isn't permitted even if I got them in my meal_params method?
Okay, I am dumb.
I just forgot the = for the hidden fields.
So instead of:
<% f.hidden_field :day, :value => local_assigns[:mealDay] %>
<% f.hidden_field :tip, :value => "Vollkost" %>
it should be:
<%= f.hidden_field :day, :value => local_assigns[:mealDay] %>
<%= f.hidden_field :tip, :value => "Vollkost" %>
Then everything is working.
Related
I need to access to the attachments values, I can't find the way
it says permitted false, it's allowed in the strong parameters though...
<ActionController::Parameters {
"utf8"=>"✓",
"authenticity_token"=>"wMY3FheLXzezCBO8phfst85DGdSBmVRl+nljAUYviYxZsWXMXC+Rcddit3XaNNikaGTvdLH+rx5ZNh6bY31Yzw==",
"finished_guitar"=><ActionController::Parameters
{ "title"=>"my super title",
"description"=>"and my awsome description"
} permitted: false>,
"commit"=>"Create Finished guitar",
"params"=>{
"attachments"=>[{"image"=>#<ActionDispatch::Http::UploadedFile:0x007fcfa084fa90 #tempfile=#<Tempfile:/var/folders/11/mdddnw8d0zd961bsfkq1cjy00000gn/T/RackMultipart20180902-64552-9bms50.jpg>,
#original_filename="image_1.jpg",
#content_type="image/jpeg",
#headers="Content-Disposition: form-data; name=\"params[attachments][][image]\";
filename=\"image_1.jpg\"\r\nContent-Type: image/jpeg\r\n">
}]
},"controller"=>"finished_guitars", "action"=>"create"} permitted: false>
my controller:
class FinishedGuitarsController < ApplicationController
def index
#finished_guitars = FinishedGuitar.all
end
def show
#finished_guitar = FinishedGuitar.find(params[:id])
end
def new
#finished_guitar = FinishedGuitar.new
#attachments = #finished_guitar.attachments.build
end
def create
#finished_guitar = FinishedGuitar.new(finished_guitar_params)
if #finished_guitar.save
unless params[:attachments].nil?
params[:attachments]['image'].each do |a|
#finished_guitar = #finished_guitar.attachments.create!(:image => a, :finished_guitar_id => #finished_guitar.id)
end
end
render json: { finishedGuitardId: #finished_guitar.id, attachments: #finished_guitar.attachments_attributes }, status: 200
else
render json: { error: #finished_guitar.errors.full_messages.join(", ") }, status: 400
end
end
private
def finished_guitar_params
params.require(:finished_guitar).permit(:title, :description, attachments_attributes: [:id, :image, :finished_guitar_id])
end
end
UPDATE
I am just adding the _form.html.erb
<div class="content">
<%= simple_form_for #finished_guitar, html: {multipart: true, id: "my-dropzone", class: "dropzone" } do |f| %>
<%= f.input :title %>
<%= f.input :description %>
<div class="dz-message needsclick">
<h3>Drop file here</h3> or
<strong>click</strong> to upload
</div>
<div class="fallback">
<br><br>
<%= f.simple_fields_for :attachments do |ff| %>
<%= ff.input_field :image, as: :file, multiple: true, name: "finished_guitar[attachments_attributes][][image]" %>
<% end %>
</div>
<br><br>
<%= f.button :submit, class: "btn btn-primary" %>
<% end %>
</div>
I can upload my files if I remove "my-dropzone", class: "dropzone"from <%= simple_form_for #finished_guitar, html: {multipart: true, id: "my-dropzone", class: "dropzone" } do |f| %>
It says name=params[attachments][][image], it seams you have something like:
params[:params][:attachments]
I'd recommend you to use rails-pry or byebug, stop the execution inside the action and you can easilly inspect the params hash and do thing like params.keys or params[:params] to see what's actually there
I have created a form but I'm having issues submitting the form, it's not getting the right route, I'm sure this is a simple fix, I'm just not seeing it.
Here are the relevant files:
new.html.erb
<%= content_for :title, "Orders & Returns" %>
<div class="title">
<h1>Orders & Returns</h1>
<p>In order for us to initialise a return of any order, first we need some information.</p>
</div>
<%= simple_form_for("/orders_and_returns/thank_you") do |f| %>
<%= f.input :order_number,
error: false,
label: false,
required: true,
placeholder: "Order Number" %>
<%= f.input :billing_name,
error: false,
label: false,
required: true,
placeholder: "Billing Name" %>
<%= f.input :email,
error: false,
label: false,
required: true,
placeholder: "Email Address" %>
<%= f.input :message,
as: :text,
error: false,
label: false,
required: true,
placeholder: "Why do you wish to initialise a return?" %>
<div class="hidden">
<%= f.input :nickname,
label: false,
required: false,
placeholder: "Captcha" %>
</div>
<%= f.submit "Submit",
class: "button-border center-100" %>
<% end %>
thank_you.html.erb
<% content_for :title, "Thank You" %>
<div class="title">
<h3>Thank you for your message!</h3>
<p>We shall get back to you soon.</p>
</div>
<section class="text-center">
<%= link_to "Go back home", root_path %>
</section>
order_and_returns_controller.rb
class OrdersAndReturnsController < ApplicationController
def new
end
def thank_you
#order_name = params[:order_name]
#billing_name = params[:billing_name]
#email = params[:email]
#message = params[:message]
OrdersAndReturnMailer.orders_and_returns(#order_number, #billing_name, #email, #message).deliver_now
end
end
orders_and_return_mailer.rb
class OrdersAndReturnMailer < ApplicationMailer
def orders_and_returns(order_number, billing_name, email, message)
#order_number = order_number
#billing_name = billing_name
#email = email
#message = message
mail(
from: email,
to: ENV['order_email'],
subject: "You have a new return query from #{email}"
)
end
end
end
routes.rb
get 'orders_and_returns/new'
post 'orders_and_returns/thank_you'
Not sure what I'm missing here, any help would be appreciated.
You must point the route to the controller and action
get 'orders_and_returns/new' => 'orders_and_returns#new'
post 'orders_and_returns/thank_you' => 'orders_and_returns#thank_you'
When I try to create an "Action" I get this error.
My Actions controller:
class ActionsController < ApplicationController
def new
#match_set = MatchSet.find(params[:match_set_id])
#fixture = #match_set.fixture
#teams = Team.where("id = " + #fixture.home_team_id.to_s + " OR id = " + #fixture.away_team_id.to_s)
#players = Player.where("team_id = " + #teams.ids.first.to_s + " OR id = " + #teams.ids.last.to_s)
#action = #match_set.actions.new
end
def create
#match_set = MatchSet.find(params[:match_set_id])
#action = #match_set.actions.new(action_params)
if #action.save
redirect_to match_set(#match_set)
else
render "actions/new"
end
end
private
def action_params
params.require(:action).permit(:team_id, :player_id, :position, :action_type, :action_result)
end
end
It is submitted from this form in views/actions/new.html.erb:
<%= form_for [#match_set, #action] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<!-- Team -->
<%= f.label :team_id %>
<%= f.collection_select :team_id, #teams,:id, :name, {include_blank: "Select team..."}, {class: "form-control"} %>
<!-- Player -->
<%= f.label :player_id %>
<%= f.collection_select :player_id, #players,:id, :last_name, {include_blank: "Select player..."}, {class: "form-control"} %>
<!-- Position -->
<%= f.label :position %>
<%= f.select :position, options_for_select(['1', '2', '3', '4', '5', '6']), {include_blank: "Select position on court..."}, class: "form-control" %>
<!-- Action Type -->
<%= f.label :action_type %>
<%= f.select :action_type, options_for_select(['Attack', 'Block', 'Pass', 'Set']), {include_blank: "Select action_type..."}, class: "form-control" %>
<!-- Action Result -->
<%= f.label :action_result %>
<%= f.select :action_result, options_for_select(['Score', 'Block', 'Pass', 'Set']), {include_blank: "Select action_type..."}, class: "form-control" %>
<!-- Submit Button -->
<%= f.submit "Add Action", class: "btn btn-primary" %>
<% end %>
Also the relevant routes:
resources :fixtures, shallow: true do
resources :match_sets, shallow: true do
resources :actions
end
end
I'm getting an error on this line in the controller:
params.require(:action).permit(:team_id,:player_id,
:position,:action_type,:action_result)
I have also noticed that my parameters seem to be disappearing but again have no clue as to the cause.
Parameters:
{"utf8"=>"✓", "authenticity_token"=>"BqbEOfL7hEA8XSMXDvMW2qQ2uR74Egp5
jJvtQlsuyV2TikZJ+6hTIEMH05gy8TM6r3ZglFDRUFBl7ScZD1czCQ==",
"commit"=>"Add Action", "match_set_id"=>"15"}
Any help is appreciated.
action is a reserved word in rails. You will need to change your model name.
Rails provides a few params on each request such as:
params[:controller] # maps to your controller name
params[:action] # maps to an action with your controllers
http://api.rubyonrails.org/classes/ActionDispatch/Routing.html
I need a form that includes 1 radio button, 1 submit button and a checkbox for each listed item.
Upon submit, the form should save a separate record for each checked item. Each saved item should include the value of the radio button along with other hidden values.
The form renders but crashes upon submit. The error message is:
undefined method `permit' for #<Array:0x007fb4b3b1a520>
My code is:
<%= form_tag(controller: "handoffs", action: "create", method: "post") %>
<%= radio_button_tag(:attend, "arrive") %>
<%= label(:handoff_arrive, "drop-off") %>
<%= radio_button_tag(:attend, "depart") %>
<%= label(:handoff_depart, "pick-up") %>
<% #parent.children.each do |child| %>
<%= check_box_tag "handoff[][check]" %>
<strong>
<%= child.fname %>
<%= child.mname %>
<%= child.lname %>
</strong><br>
<% group = Group.find(child.group_id) %>
<%= hidden_field_tag "handoff[][attend]" %>
<%= hidden_field_tag "handoff[][group_name]", :value => group.name %>
<%= hidden_field_tag "handoff[][child_id]", :value => child.id %>
<%= hidden_field_tag "handoff[][center_id]", :value => #center.id %>
<%= hidden_field_tag "handoff[][escort_fname]", :value => #parent.fname %>
<%= hidden_field_tag "handoff[][escort_lname]", :value => #parent.lname %>
<%= hidden_field_tag "handoff[][child_fname]", :value => child.fname %>
<%= hidden_field_tag "handoff[][child_mname]", :value => child.mname %>
<%= hidden_field_tag "handoff[][child_lname]", :value => child.lname %>
<% end %>
<%= button_to :submit, :class => 'f_submit' %>
<% end %>
Controller actions:
def new
#handoff = Handoff.new
#parent = current_parent
#center = Center.find(#parent.center_id)
end
def create
params["handoff"].each do |handoff|
if params[:handoff["check"]] != ""
#handoff = Handoff.new(handoff_params)
#handoff.save
end
end
end
def handoff_params
params.require(:handoff).permit(:attend, :group_name, :child_id, :center_id, :escort_fname, :escort_lname, :child_fname, :child_mname, :child_lname)
end
Request parameters (in error report)
{"utf8"=>"✓",
"authenticity_token"=>"snqrS130bXNV4bmMHOMlXeyhX2rWFVpmY/PYIv0jn97MBOLSWWw2jBbeYGPyjt7O9l5pRVNuFiu1qOwkGpELTA==",
"attend"=>"depart", "handoff"=>[{"check"=>"1", "attend"=>"",
"group_name"=>"{:value=>\"Gifted\"}", "child_id"=>"{:value=>60}",
"center_id"=>"{:value=>4}", "escort_fname"=>"{:value=>\"Richard\"}",
"escort_lname"=>"{:value=>\"Messing\"}",
"child_fname"=>"{:value=>\"Aaron\"}",
"child_mname"=>"{:value=>\"Lawrence\"}",
"child_lname"=>"{:value=>\"Schwartz\"}"}, {"check"=>"1", "attend"=>"",
"group_name"=>"{:value=>\"Arts & Crafts\"}",
"child_id"=>"{:value=>61}", "center_id"=>"{:value=>4}",
"escort_fname"=>"{:value=>\"Richard\"}",
"escort_lname"=>"{:value=>\"Messing\"}",
"child_fname"=>"{:value=>\"Joseph\"}",
"child_mname"=>"{:value=>\"Michael\"}",
"child_lname"=>"{:value=>\"Messing\"}"}], "method"=>"post",
"controller"=>"handoffs", "action"=>"create"}
I had similar case. First you need to create array with all values that you would like to export I used helper to do that. I'll show you my example:
def get_table_of_keywords(keywords)
exact_keywords = []
keyword_array.each do |key|
if !key.blank?
exact_keywords << {keyword: key, created_at: DateTime.now.in_time_zone, updated_at: DateTime.now.in_time_zone }
end
end
exact_keywords
end
And the you are using create:
#inserted_keywords = #campaign.keywords.create(get_table_of_keywords(params[:keyword][:keyword])) # add new keywords to the list
I'm starting in rails and I have this error that I'm not able to solve..
Error - param is missing or the value is empty:
personas_x_tipos_persona
Controller
class PersonasController < ApplicationController
def create_cliente
#cliente = Persona.new(persona_params)
#personas_x_tipos_personas = Persona.new(tipos_personas_params)
if #cliente.save
redirect_to show_clientes_path
else
render :new_cliente
end
end
private
def persona_params
params.require(:persona).permit(:nombre, :apellido, :direccion, :ruc, :contacto, :email)
end
def tipos_personas_params
params.require(:personas_x_tipos_persona).permit(:linea_credito)
end
end
view
<div>
<%= form_for :persona ,:url => add_cliente_path, :html => {:method => :post} do |f|%>
<% #cliente.errors.full_messages.each do |message| %>
<div class="alert alert-danger" margin-top:10px">
* <%=message%>
</div>
<% end %>
<%= f.text_field :nombre, placeholder: "Nombre del Cliente"%>
<%= f.text_field :apellido, placeholder: "Apellido del Cliente"%>
<%= f.text_field :direccion, placeholder: "Direccion del Cliente"%>
<%= f.text_field :ruc, placeholder: "RUC del Cliente"%>
<%= f.text_field :contacto, placeholder: "Contacto del Cliente"%>
<%= f.email_field :email, placeholder: "Email del Cliente""%>
<%= f.fields_for :personas_x_tipos_persona do |pxp|%>
<%= pxp.number_field :linea_credito, placeholder: "Linea de Credito del Cliente"%>
<% end %>
<%= f.submit 'Guardar'%>
<% end %>
</div>
param is missing or the value is empty: personas_x_tipos_persona
The problem is with this line #personas_x_tipos_personas = Persona.new(tipos_personas_params)(actually this is not needed) which is calling tipos_personas_params.
From the docs of require(key),
When passed a single key, if it exists and its associated value is
either present or the singleton false, returns said value
Otherwise raises ActionController::ParameterMissing
So, in your case the require is expecting :personas_x_tipos_persona, while this is missing in the params, so is the error.
Actually, the form object is :persona not :personas_x_tipos_persona. Also as I can see that you are using fields_for, so you need to whitelist :personas_x_tipos_persona_attributes inside persona_params and the tipos_personas_params method is not needed. The below code should get you going.
class PersonasController < ApplicationController
def create_cliente
#cliente = Persona.new(persona_params)
#this is not needed
##personas_x_tipos_personas = Persona.new(tipos_personas_params)
if #cliente.save
redirect_to show_clientes_path
else
render :new_cliente
end
end
private
def persona_params
params.require(:persona).permit(:nombre, :apellido, :direccion, :ruc, :contacto, :email, personas_x_tipos_persona_attributes: [:id, :linea_credito])
end
end