Accessing values of ActionController Parameters - ruby-on-rails

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

Related

Rails7 Active Srorage could not update my image.[param is missing or the value is empty: activity]

I try to upload image with active storage and cropper.js. so It works with first upload image doing well. but when I try to not attached any image and submit form, that will get error [param is missing or the value is empty: activity].
is there anyone helping me?
controller
def update_image
#activity = Activity.friendly.find(params[:id])
#activity.update(activity_params)
if #activity.save
redirect_to management_path(#activity)
else
render 'edit_image_modal'
end
end
def activity_params
params.require(:activity).permit(:image, :crop_x, :crop_y, :crop_width, :crop_height, :custom_url)
end
view
<%= simple_form_for #activity, url: {action: 'update_image'}, data: { turbo: false, controller: 'validate', validate_target: 'form' } do |f| %>
<div data-controller='image-upload image-cropper' data-image-cropper-model-value='activity'
data-image-upload-token-value="<%= direct_upload_token("Activity#image") %>"
data-image-upload-attachment-value='Activity#image'>
<%= f.file_field :image, 'data-image-upload-target': 'input', 'data-action': 'image-upload#changed' %>
<p>
<% set_image = #activity.image.attached? ? #activity.image.variant(#activity.crop_constraints) : "https://res.cloudinary.com/hanfn5d8l/image/authenticated/s--lp_ZlvDw--/v1649146879/main/no_image.png" %>
<%= image_tag set_image, class: 'w-full rounded mb-4', 'data-image-upload-target': 'photo', 'data-image-cropper-target': 'photo',
'data-action': 'image-uploaded->image-cropper#changed' %>
</p>
</div>
<div class="text-center">
<%= f.button :submit, 'submit', data: { action: 'validate#submitForm'} %>
</div>
<% end %>
model
class Activity < ApplicationRecord
has_one_attached :image
def crop_constraints
return {} unless crop_x && crop_y && crop_width && crop_height
{ crop: [crop_x.to_f, crop_y.to_f, (crop_width + crop_x).to_f, (crop_height + crop_y).to_f] }
end
validates :image,
content_type: %i(gif png jpg jpeg),
size: { less_than_or_equal_to: 5.megabytes },
dimension: { width: { max: 3000 }, height: { max: 3000 } }
end

Rails 6 change params to hash of hashes

I've got an app where the user has to fill out a survey. I need to store user's answers in inside TestResult model which have only one field answers:string
With current implementation I'm getting params from the form as:
params => {
{
"question_#{id}": "some answer 1",
"question_#{id}": "some answer 12345",
}
}
Which I want to change to the below structure:
# expected hash params
params => {
{
question: 'first question',
answer: 'some answer 1'
},
{
question: 'second question',
answer: 'some answer 123431'
}
}
What should I change (probably in a view) to get this hash?
new.html.erb
<%= simple_form_for :test_results, url: test_results_path do |f| %>
<% #randomize_questions.map do |q| %>
<%= q[:question] %>
<%= f.input "question_#{q[:id]}", collection: q[:answers], as: :radio_buttons %>
<% end %>
<%= f.button :submit %>
<% end %>
controller:
class TestResultsController < ApplicationController
before_action :fetch_random_questions, only: [:new, :create]
def new
#test_result = TestResult.new
end
def create
#test_result = TestResult.new(
answer: test_result_params,
)
#test_result.save
redirect_to dummy_path
end
end
private
def test_result_params
params.require(:test_results).permit!
end
def fetch_random_questions
TestQuestion.where(published: true).order('RANDOM()')
#randomize_questions = test_questions.map do |obj|
{
id: obj.id,
question: obj.question,
answers: [obj.correct_answer, obj.other_answer1, obj.other_answer2, obj.other_answer3],
}
end
end
end
TestResult model
class TestResult < ApplicationRecord
serialize :answer, Hash
serialize :answer, String
validates :answer, presence: true
end
The params get his structure from the input names.
So you could add an hidden field for question, and then specify a name for both of your fields.
<%= simple_form_for :test_results, url: test_results_path do |f| %>
<% #randomize_questions.map do |q| %>
<%= q[:question] %>
<%= f.input "question_#{q[:id]}", as: :hidden, input_html: { name: "test_results[#{q[:id]}][question]", value: q[:question] } %>
<%= f.input "question_#{q[:id]}", collection: q[:answers], as: :radio_buttons, input_html: { name: "test_results[#{q[:id]}][answer]" } %>
<% end %>
<%= f.button :submit %>
<% end %>
Params should looks like this:
params => {
test_result: {
1 => {
question: "...",
answer: "..."
},
2 => {
question: "...",
answer: "..."
}
}
}
Not tested. Could you tell if that's works for you?

Ruby On Rails: Parameters - Permitted: false

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.

Getting an "undefined method `permit' for "create"" error when submitting form

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

Error "param is missing or the value is empty: personas_x_tipos_persona"

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

Resources