Rails: ForbiddenAttributesError for dynamic simple form - ruby-on-rails

I followed the answer given here to create a simple dynamic form (not nested). The idea is to invite several people with their email. Then I have an "Add Team Member" button to add the fields to enter the coworker email.
I get the following error but I don't know why:
ActiveModel::ForbiddenAttributesError in InvitationsController#create
The parameters:
{"utf8"=>"✓",
"authenticity_token"=>"zLs8DWkzO+bPc2jGhFptgc+BAGAwzr1kcn/hkX/6vQbQ/cDCzuqoGCMGUTcYHs+up7nBzHFiEXVcKustyL1KIA==",
"invitation"=>[{"email"=>"test#test.fr", "_destroy"=>"false", "user_id"=>"1"}, {"email"=>"test2#test2.fr", "_destroy"=>"false", "user_id"=>"1"}],
"commit"=>"Save Team Members"}
My create action and invitation_params in the controller:
def create
puts params[:invitation].to_yaml
params[:invitation].each do |invitation_params|
Invitation.create(invitation_params)
end
redirect_to invitation_path
end
def invitation_params
params.require(:invitation).permit(:id, :email, :user_id, :_destroy, :token)
end
My form:
<%= form_for(invitation) do |f| %>
<% if invitation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(invitation.errors.count, "error") %> prohibited this invitation from being saved:</h2>
<ul>
<% invitation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div id="container_invitations"></div>
<%= link_to "Add a New Team Member", add_invitation_path, :method => :post, :remote => true %>
<div class="actions">
<%= f.submit "Save Team Members", class: "cta2" %>
</div>
<% end %>
add_invitation controller action (to add the fields dynamically):
def add_invitation
respond_to do |format|
format.js
end
end
add_invitation.js.erb:
$('#container_invitations').append("<%= escape_javascript(render :partial => 'invitation_fields_render') %>");
$('.remove_fields').on('click', function(e) {
$(this).parent().remove();
});
_invitation_fields_render.html.erb (the partial with the fields)
<div class="new_invitation_row">
<%= email_field_tag "invitation[][email]", nil, placeholder: "Team Member Email", :required => 'required' %>
<%= hidden_field_tag "invitation[][_destroy]", nil, value: false %>
<a class="remove-link remove_fields dynamic" href="#"><i class="fa fa-trash fa-lg" title="Remove"></i></a>
<%= hidden_field_tag "invitation[][user_id]", nil, value: current_user.id %>
</div>
My invitation model:
class Invitation < ActiveRecord::Base
has_secure_token
belongs_to :user
end
Thank you.
UPDATE
I added the new params.permit line proposed by IngoAlbers. I still get the error. Here is the full stacktrace of the error:
Started POST "/invitations" for 127.0.0.1 at 2017-12-01 07:49:02 +0000
Processing by InvitationsController#create as HTML Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"pV5wQj3QHXksNEtJ8nZSjWDc8VyHiewVCt4A1+ijH8G5GIyNmgmOh8BBcrhuMvCiCOQw8MYlQAQkiwprX+To5w==",
"invitation"=>[{"email"=>"test#test.fr", "_destroy"=>"false",
"user_id"=>"1"}], "commit"=>"Save Team Members"} User Load (0.4ms)
SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY
"users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]] CoreBot Load
(0.2ms) SELECT "core_bots".* FROM "core_bots" WHERE "core_bots"."id"
= ? LIMIT ? [["id", 1], ["LIMIT", 1]] Completed 500 Internal Server Error in 4ms (ActiveRecord: 0.6ms)
ActiveModel::ForbiddenAttributesError
(ActiveModel::ForbiddenAttributesError):
app/controllers/invitations_controller.rb:35:in block in create'
app/controllers/invitations_controller.rb:34:ineach'
app/controllers/invitations_controller.rb:34:in `create' Rendering
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout Rendering
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
(5.3ms) Rendering
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb Rendered
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.5ms) Rendering
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
(1.5ms) Rendered
/Users/nicolasleroux/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout (93.1ms)

The problem is that invitation is an array. So you actually need to permit the array in the invitation_params.
def invitation_params
params.permit(invitation: [:id, :email, :user_id, :_destroy, :token])
end
In addition you have a problem in the create action itself.
You don't actually use the permitted parameters, that was defined.
It should probably look like this:
def create
invitation_params[:invitation].each do |invitation|
Invitation.create(invitation)
end
redirect_to invitation_path
end

Related

ActionController::UnknownFormat with js

Im new at ruby and I try to add ajax for my controller, but I`m probably missing something
My controller
class StocksController < ApplicationController
def search
if params[:stock].present?
#stock = Stock.new_lookup(params[:stock])
if #stock
respond_to do |format|
format.js {render partial: 'users/result'}
end
else
flash[:alert] = "Please enter a valid symbol to search"
redirect_to my_portfolio_path
end
else
flash[:alert] = "Please enter a symbol to search"
redirect_to my_portfolio_path
end
end
end
My view. When I`m not writing 'turbo:false' nothing happens
<div class="search-area">
<h3>Search Stocks</h3>
<%= form_tag search_stock_path, data: {turbo: false}, method: :get do %>
<div class="form-group row">
<div class="col-sm-9 no-right-padding">
<%= text_field_tag :stock, params[:stock], placeholder: "Stock ticker symbol", autofocus: true, class: "form-control form-control-large"%>
</div>
<div class="col-sm-3 no-left-padding">
<%= button_tag type: :submit, class: "btn btn-success" do %>
<%= fa_icon 'search 1.5x' %>
<% end %>
</div>
</div>
<% end %>
</div>
My terminal:
Started GET "/search_stock?stock=MSFT&button=" for 127.0.0.1 at 2023-01-27 22:44:35 +0200
Processing by StocksController#search as HTML
Parameters: {"stock"=>"MSFT", "button"=>""}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Completed 406 Not Acceptable in 1701ms (ActiveRecord: 1.2ms | Allocations: 8322)
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/stocks_controller.rb:6:in `search'
Error image
I found articles with a similar error, but there was no answer
In the terminal I see that but dont know what to do
Processing by StocksController#search as HTML

Passing an ID through a hidden form field

I tried to do something similar to this in a form, but get this error:
Started POST "/opinions" for 127.0.0.1 at 2019-01-03 17:11:12 -0800
Processing by OpinionsController#create as JS
Parameters: {"utf8"=>"✓", "opinion"=>{"content"=>"This is an opinion"}, "type_of"=>"pro", "topicId"=>"{:value=>2}", "commit"=>"Create Opinion"}
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Topic Load (0.0ms) SELECT "topics".* FROM "topics" WHERE "topics"."id" = ? LIMIT ? [["id", nil], ["LIMIT", 1]]
Completed 404 Not Found in 3ms (ActiveRecord: 0.0ms)
ActiveRecord::RecordNotFound (Couldn't find Topic with 'id'=):
app/controllers/opinions_controller.rb:6:in `create'
opinions_form.html.erb:
<%= form_for(opinion, :html=> {class:"form-horizontal", role:"form"}, remote: true) do |f| %>
<div class="form-group">
<div class="col-sm-12">
<%= f.text_area :content, rows:4, class: "form-control", placeholder: "Opinion" %>
</div>
</div>
<%= hidden_field_tag 'type_of', typeOf %>
<%= hidden_field_tag :topicId, :value => #topic.id %>
<% puts "ID: " + #topic.id.to_s %>
<div class="form-group">
<div class="col-sm-12">
<%= f.submit %>
</div>
</div>
<% end %>
Relevant code in controller:
def create
#opinion = Opinion.new(opinion_params)
#opinion.user = current_user
#opinion.topic = Topic.find(params[:opinion][:topicId])
if #opinion.save
flash[:success] = 'Opinion Added'
else
puts #opinion.errors.full_messages
flash[:danger] = 'Opinion not Added'
end
end
private
def opinion_params
params.require(:opinion).permit(:content, :type_of)
end
and finally, relevant code in the topic show page:
<td>
<%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic => #topic %>
</td>
<td>
<%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => #topic %>
</td>
As you can see in the request parameters:
Parameters: {"utf8"=>"✓", "opinion"=>{"content"=>"This is an opinion"}, "type_of"=>"pro", "topicId"=>"{:value=>2}", "commit"=>"Create Opinion"}
The topicId parameter is not nested under opinion, so you need to change your finder to:
#opinion.topic = Topic.find(params[:topicId][:value])
You can also remove the superfluous value key in your view:
<%= hidden_field_tag :topicId, #topic.id %>
Which would further simplify your finder:
#opinion.topic = Topic.find(params[:topicId])
As an aside. Note that idiomatic ruby calls for snake_case in all identifiers. This won't change how your code works, but it will help other Ruby developers read your code.

Paperclip image not showing, unpermitted params and routing error

I'm trying to display images on the homepage with paperclip and I have unpermitted params and a routing error. I have tried various solutions including trying to pass in an array but I think this is happening because of my own lack of knowledge about rails.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Hdw1RzedMZdUE0cPrAXz0fkctQKfW9HX3S5ZwYh4lr0PwTJhHhVwcrglJv5qrMQF3T5YkcJZ9zBiRRRlCoNCNQ==", "document"=>{"doc"=>[#<ActionDispatch::Http::UploadedFile:0x007feaf2db80f0 #tempfile=#<Tempfile:/var/folders/1q/zfrk5kxj1015crsc13jwwrz40000gp/T/RackMultipart20170608-15326-1pcmtgl.jpg>, #original_filename="P1150645.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"document[doc][]\"; filename=\"P1150645.jpg\"\r\nContent-Type: image/jpeg\r\n">]}, "commit"=>"Upload Document"}
Unpermitted parameter: doc
(1.9ms) begin transaction
SQL (2.0ms) INSERT INTO "documents" ("created_at", "updated_at") VALUES (?, ?) [["created_at", 2017-06-08 04:47:55 UTC], ["updated_at", 2017-06-08 04:47:55 UTC]]
(0.8ms) commit transaction
Redirected to http://localhost:3000/
Completed 302 Found in 46ms (ActiveRecord: 4.8ms)
Started GET "/" for ::1 at 2017-06-08 12:47:55 +0800
Processing by PagesController#home as HTML
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 3], ["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" LIMIT ? [["LIMIT", 1]]
Rendering pages/home.html.erb within layouts/application
Document Load (3.1ms) SELECT "documents".* FROM "documents" ORDER BY created_at
Rendered documents/_documents.html.erb (56.7ms)
Rendered documents/_new.html.erb (4.2ms)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE ("users"."id" != 3)
Conversation Load (0.2ms) SELECT "conversations".* FROM "conversations" WHERE (conversations.sender_id = 3 OR conversations.recipient_id = 3)
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.2ms) SELECT COUNT(*) FROM "messages" WHERE "messages"."conversation_id" = ? [["conversation_id", 4]]
Rendered conversations/_index.html.erb (18.5ms)
Rendered pages/home.html.erb within layouts/application (141.2ms)
Rendered shared/_navbar.html.erb (5.2ms)
Completed 200 OK in 426ms (Views: 401.3ms | ActiveRecord: 6.2ms)
Started GET "/docs/original/missing.png" for ::1 at 2017-06-08 12:47:56 +0800
ActionController::RoutingError (No route matches [GET] "/docs/original/missing.png"):
I've tried nesting the params given that document => doc is passing to an array, even if I leave the params blank it still uploads to the database with null fields and routing error, DocumentsController:
def doc_params
params.require(:document).permit(:id, :doc)
end
I've tried multiple validations in here:
class Document < ApplicationRecord
has_attached_file :doc
do_not_validate_attachment_file_type :doc
end
I wondering if rendering the index is causing the routing error as I got rid of temporarily by re-routing but the image was still null, documents/_index.html.erb
<div class="container">
<div class="row around-xs">
<center>
<% #documents.each do |document| %>
<li class="col-xs-3" id="item-grid">
<%= link_to image_tag(document.doc.url, class: 'media-object', size:"108x152"), document.doc.url, target: '_blank' %>
<% if #users %>
<% if current_user.is_admin? %>
<%= link_to 'Remove', document_path(document), class: 'btn btn-danger', method: :delete, data: {confirm: 'Are you sure?'} %>
<% end %>
<% end %>
</li>
<% end %>
</center>
</div>
</div>
home.html.erb
<section id="about" class="about-section">
<div class="container" id="services">
<div class="col-lg-8 col-md-offset-2" id="progpos"><h1>My Work</h1></div>
<%= render 'documents/index' %>
<br>
<%= render 'documents/new' %>
</div>
</section>
Please please help! thanks! documents/_new.html.erb
<% if #users %>
<% if current_user.is_admin? %>
<%= form_for #document, html: { multipart: true } do |f| %>
<% if #document.errors.any? %>
<div id="error_explanation">
<h2>
<%= "#{pluralize(#document.errors.count, "error")} prohibited this document from being saved:" %>
</h2>
<ul>
<% #document.errors.full_messages.each do |msg| %>
<li>
<%= msg %>
</li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group" style="width: 20%">
<%= f.file_field :doc, class: 'form-control', placeholder: "Document", multiple: true %>
</div>
<div class="form-group">
<%= f.submit 'Upload Document', class: 'btn btn-default' %>
</div>
<% end %>
<% end %>
<% end %>
Here's the whole of the controller and I've edited documents/_new.html.erb to how it looks:
class DocumentsController < ApplicationController
def index
#documents = Document.order('created_at')
end
def new
#document = Document.find(params[:id])
end
def create
#document = Document.new(doc_params)
if #document.save
**params[:document][:doc].each do |d| #iterate over multiple attached files
#document.create(doc: d)**
end
flash[:success] = "The document was added!"
redirect_to root_path
else
render '_new'
end
end
def destroy
#document = Document.find(params[:id])
if #document.destroy
flash[:notice] = "Successfully deleted photo!"
redirect_to root_path
else
flash[:alert] = "Error deleting photo!"
end
end
private
def doc_params
params.require(:document).permit(:id, **document: {doc: []}**)
end
end
I've added Pavans code to mine and i've also changed the params at the bottom which now gives me undefined method `create' for #. I think that's progress?
Unpermitted parameter: doc
You have multiple :true set for field doc, so doc should an array to accept the values. You should change the doc_params to below
def doc_params
params.require(:document).permit(:id, doc: [])
end
No handler found for
[#,
#original_filename="P1150645.jpg", #content_type="image/jpeg",
#headers="Content-Disposition: form-data; name=\"document[doc][]\";
filename=\"P1150645.jpg\"\r\nContent-Type: image/jpeg\r\n">]
You should also set multipart: true to the form to handle file uploads
<%= form_for #document, html: { multipart: true } do |f| %>
ActionController::RoutingError (No route matches [GET]
"/docs/original/missing.png")
Paperclip will try to find missing.png when an object doesn't have an uploaded file and you have tell Paperclip where to find it!
class Document < ApplicationRecord
has_attached_file :doc, :styles => { :medium => "250x250>", :thumb => "150x150>" }, :default_url => "/system/:attachment/:style/missing.jpg"
do_not_validate_attachment_file_type :doc
end
Update:
Your create action should look like below
def create
#document = Document.new(doc_params)
if #document.save
params[:document][:doc].each do |d| #iterate over multiple attached files
#doumnet.create(doc: d)
end
flash[:success] = "The document was added!"
redirect_to root_path
else
render 'new'
end
end

Unable to save form

I'm trying to save a form, and I am so lost on why it refuses to save. Does anybod have a clue what might be wrong?
Here's the form code:
<%= form_for #service, url: services_path do |f| %>
<% #profiles.each do |profile| %>
<%= f.text_field :service_id, value: "#{profile.service_id}" %>
<div class="media">
<a class="media-left" href="#">
<%= image_tag profile.avatar, height: '45', width: '45', class: 'img-circle' %>
</a>
<div class="media-body">
<h4 class="media-heading"><%= profile.service_username %></h4>
<%= profile.service %>
</div>
</div>
<% end %>
<%= f.submit %>
<% end %>
and
#service = current_user.services.new
the association between them are:
user has_many :services
service belongs_to :user
and the services controller create looks like this:
def create
#service = current_user.services.new(service_params)
if #service.save
flash[:notice] = "success"
redirect_to root_url
else
flash[:alert] = "Unable to add"
redirect_to :back
end
end
my logs say:
Started POST "/services" for 127.0.0.1 at 2015-01-17 18:09:44 -0800
Processing by ServicesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"lsW5aVuVUCQrHsaCo+uxbR11sF3mph3lTnM8O/Dtxn8=", "service"=> {"service_id"=>"2967861508"}, "commit"=>"Create Service"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 30 ORDER BY "users"."id" ASC LIMIT 1
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Redirected to http://localhost:3000/schedules
Completed 302 Found in 9ms (ActiveRecord: 1.1ms)
Oops, minor edit below (#service.errors instead of #validation.errors):
From your logs, you can see that you got into the controller create method and the save failed. This is usually a validation problem but I can't tell from what you posted. I would put #service.errors into the flash instead of just "unable to add". This should help you and future users see what's going on when the create fails.

Ruby on rails: create action doesn't work, while new, edit and update (the same form as in create !) actions works - why?

I have Realization model:
# encoding : utf-8
class Realization < ActiveRecord::Base
attr_accessible :city, :street, :title, :work, :photo, :date
has_attached_file :photo
end
Controller:
# encoding : utf-8
class RealizationsController < ApplicationController
before_filter :admin_required, :except => [:index,:show]
# GET /realization/new
def new
#realization = Realization.new
#realization.date = Time.now.__send__(:to_date).to_s
end
# POST /realization
def create
#realization = Realization.new(params[:realization])
if #realization.save
redirect_to #realization, notice: 'realization was successfully created.'
else
render action: "new"
end
end
(...) others
View of form:
<%= form_for #realization, :html => { :multipart => true } do |f| %>
<% if #realization.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#realization.errors.count, "error") %> prohibited this realization from being saved:</h2>
<ul>
<% #realization.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
(...)
<div class="field">
<%= f.file_field :photo %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
And routes :
resources :realizations
And WEBrick server info is that:
Started POST "/realizacje" for 127.0.0.1 at 2013-04-12 12:26:35 +0200
Processing by RealizationsController#index as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"zK5jP4ChBBY+R21TjrZkp4xGvCHViTFJ+8Fw6Og28YY=", "realization"=>{"title"=>"wwwwww", "street"=>"", "city"=>"", "work"=>"", "date"=>"2013-04-12"}, "commit"=>"Submit"}
(1.0ms) SELECT COUNT(*) FROM "realizations"
Realization Load (2.0ms) SELECT "realizations".* FROM "realizations" ORDER BY created_at DESC LIMIT 7 OFFSET 0
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Rendered realizations/index.html.erb within layouts/application (156.0ms)
Completed 200 OK in 340ms (Views: 333.0ms | ActiveRecord: 4.0ms)
While I use the form and push the submit it redirects/randers realizations/index without notice or errors even!
I have completely no idea why? Especialy that it worked before...
Maybe javascript added later on may be the reason?
Paperclip works well in update so it isn't it...
You might check your new action to see what you're passing in to the form_for.
You want to be passing in a brand new instance of your Realization model.
i.e. in the new action you should have a line that reads #realization = Realization.new
The reason I suggest this is because form_for calls a method (#new_record?) on the object you give it and will submit a post or put request depending on whether that method call returns true or false.

Resources