Unpermitted parameters for form_with(:url) in Rails 5 - ruby-on-rails

I have:
<%= form_with url: retrieve_videos_path, local: true do |form| %>
# some form stuff
<%= form.submit %>
<% end %>
And when I submit it, logs signal about unpermitted parameters: Unpermitted parameters: :utf8, :authenticity_token, :commit
I guess, in forms for models these parameters are permitted by the 'require' method like:
params.require(:model).permit(:params_stuff)
But how to make the same for urls?

Related

Rails with Uppy XHRUpload: How to get the #model into the params hash?

I'm trying to get Uppy jiving with a Rails upload form, but I'm having trouble getting it setup properly. The resulting params hash is missing its initial :image object. In a typical Rails form, I assume this is taken care of whenever its bound to a model instance. But I'm not sure how to do something like that with an Uppy form.
Just thinking out loud here, but maybe it has something to do with how I'm setting the endpoint option?
EDIT: And to clarify, I'm just trying to get it setup for a development environment, using localhost:3000 and storing everything locally for now
Here's the "standard" Rails form (withOUT uppy):
<%= form_for #image, html: { multipart: true } do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.label :file %><br>
<%= f.file_field :file %>
</div>
<div class="actions">
<%= f.submit "Upload Images" %>
</div>
<% end %>
And its resulting params hash:
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"Cr9NAN6NE9JV6HrI7RE7EmjmxqnlfbWk+LT5k9yLuq1Sm0L9E/zJ/eXCDcjbyw7A6lUHP2LFBqbfjY+SWoeO+w==", "image"=>{"file"=>#<ActionDispatch::Http::UploadedFile:0x000055d297d74168 #tempfile=#<Tempfile:/tmp/RackMultipart20200328-12356-1qjsycd.png>, #original_filename="Screenshot from 2019-07-22 04-24-23.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"image[file]\"; filename=\"Screenshot from 2019-07-22 04-24-23.png\"\r\nContent-Type: image/png\r\n">}, "commit"=>"Upload Images", "controller"=>"images", "action"=>"create"} permitted: false>
And here's my attempt at an Uppy form:
<%= form_for #image, html: { id: "uppy-form" } do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.hidden_field :file, multiple: true, name: "images[file]", value: #image.file_data,
accept: 'image/jpg,image/jpeg,image/gif,image/png,image/tif,image/tiff', class: "upload-hidden" %>
<%= hidden_field_tag :authenticity_token, form_authenticity_token, id: :form_token %>
<% end %>
<script>
const XHRUpload = Uppy.XHRUpload
var uppy = Uppy.Core()
.use(Uppy.Dashboard, {
inline: true,
target: '#uppy-form'
})
.use(XHRUpload, {
endpoint: '/images',
fieldName: 'images[file]'
})
.setMeta({
authenticity_token: $("#form_token").attr('value')
})
uppy.on('complete', (result) => {
console.log(`Upload complete! We've uploaded these files:`, result.successful)
})
</script>
The resulting error when calling $ params
Completed 400 Bad Request in 5328ms (ActiveRecord: 0.4ms | Allocations: 40383)
ActionController::ParameterMissing - param is missing or the value is empty: image:
And the params in full
=> <ActionController::Parameters {"authenticity_token"=>"CYUz9AszYR4G0WEiI4bDoOlUyH4jFMzAVRf4vF6m6OJRoTwJxkK7Mbb7FiIVXPZya+cJ6KSsf8JyLo692KrctA==", "relativePath"=>"null", "name"=>"Screenshot from 2019-07-10 06-34-34.png", "type"=>"image/png", "exifdata"=>"[object Object]", "images"=>{"file"=>#<ActionDispatch::Http::UploadedFile:0x000055d2962c49d0 #tempfile=#<Tempfile:/tmp/RackMultipart20200328-12359-1d093y1.png>, #original_filename="Screenshot from 2019-07-10 06-34-34.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"images[file]\"; filename=\"Screenshot from 2019-07-10 06-34-34.png\"\r\nContent-Type: image/png\r\n">}, "controller"=>"images", "action"=>"create"} permitted: false>
In the ImagesController, here is how image_params is defined. It's that initial .require(:image) that I think is missing when it gets sent over:
def image_params
params.require(:image).
permit(...)
end
Got it!
Had a typo in the fieldName
I previously had it as images[file], it should be image[file]

Ruby Blog Tutorial - ActionController::InvalidAuthenticityToken

I am completing the Ruby Rails tutorial for a blog and when I try and submit a new post I am getting a ActionController::InvalidAuthenticityToken error from the browser.
I am new to Ruby Rails (hence why I am doing the tutorial) and I have been back through the examples and have looked a various other answers etc and I cannot seem to find what the problem could be? I would like to understand the problem and how to fix it as part of learning.
This is what is shown in the extracted source :
def handle_unverified_request
raise ActionController::InvalidAuthenticityToken
end
end
end
This is from the Server :
Parameters: {"authenticity_token"=>"MijxdOhNKeov89oetl7Xa0KWpSZoeb3WAIuX0RECyIusjfjs/B5megtnH6JFOSG1G5K7g+csApABCn31UxdYGg==", "article"=>{"title"=>"po request"
, "text"=>"I want to buy some cheese"}, "commit"=>"Save Article"}
HTTP Origin header (https://3000-dot-4708054-dot-devshell.appspot.com) didn't match request.base_url (https://127.0.0.1:3000)
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 499)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
And this is the .erb for a new record:
<%= form_with scope: :article, url: articles_path, local: true do |form|
%>
<% end %>
<%= link_to 'Back', articles_path %>
<%= form_with scope: :article, url: articles_path, local: true do |form|
%>
<p>
<%= form.label :title %><br>
<%= form.text_field :title %>
</p>
<p>
<%= form.label :text %><br>
<%= form.text_area :text %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
The authenticity token is used by rails to ensure that requests come from the site rails is expecting. When it generates a form, it includes the verification token for this purpose. There's a much better explanation of the history / why it's used here:
Understanding the Rails Authenticity Token
If you want to keep the checks in, then the short answer is to include
<%= form_authenticity_token %>
In any views that generate forms. This will ensure the correct token is in the form, and prevent the error from occuring

form_with does not redirect when it ought to

I'm struggling with what I think is a very simple error, and yet I don't have the Rails sophistication to detect where that error is.
I have the following form:
<%= form_with(url: '/bills/viewer', method: :get) do |f| %>
<%= f.label :congress, 'Congress (i.e. 112)' %>
<%= f.number_field :congress, class: 'form-control' %>
<%= f.label :bill_type, 'Bill type' %>
<%= f.radio_button :bill_type, 'hr' %><%= ' House of Representatives' %>
<%= f.radio_button :bill_type, 's' %><%= ' Senate' %>
<%= f.radio_button :bill_type, 'hjres' %> <%= 'House Joint Resolution' %>
<%= f.radio_button :bill_type, 'sjres' %><%= ' Senate Joint Resolution' %>
<%= f.radio_button :bill_type, 'hconres' %><%= ' House Concurrent Resolution' %>
<%= f.radio_button :bill_type, 'sconres' %><%= ' Senate Concurrent Resolution' %>
<%= f.radio_button :bill_type, 'hres' %><%= ' House Resolution' %>
<%= f.radio_button :bill_type, 'sres' %><%= ' Senate Resolution' %>
<%= f.label :bill_number, 'Bill number' %>
<%= f.number_field :bill_number, class: 'form-control' %>
<%= f.submit "Submit", class: 'form-control' %>
<% end %>
In my config/routes.rb file, I have the following line:
get '/bills/viewer', to: 'bills#show'
The idea is that I want the form to transfer the submitted information to the "show" action in my bills_controller.rb file, which I give below...
def show
#bill = Bill.where("congress = ? AND bill_type = ? AND bill_number = ?", bill_params[:congress], bill_params[:bill_type], bill_params[:bill_number]).take
if #bill.nil?
create
end
#bill_xml = RestClient.get(bill_params[:bill_link])
render :xml => #bill_xml
puts "Called to show!"
...and then for the user to be redirected to corresponding show.html.erb file, which I give below...
<% provide(:title, "#{ #bill[:congress] } #{ #bill[:bill_type].upcase } #{ #bill[:bill_number] } | ") %>
<h1><%= "#{ #bill[:congress] } #{ #bill[:bill_type].upcase } #{ #bill[:bill_number] }" %></h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= puts #bill_xml %>
<%= render #bill_xml %>
</div>
</div>
<% puts "RENDERED..." %>
The two "puts" lines are in there for my own debugging purpose. The one in the show method behaves as expected, and my console displays "Called to show!". The other puts line, "RENDERED..." is not displayed. Moreover, the process completes to 200 OK.
I include my console's output upon clicking "Submit" below...
Started GET "/bills/viewer?utf8=%E2%9C%93&congress=112&bill_type=hr&bill_number=1027&commit=Submit" for 127.0.0.1 at 2018-07-05 15:05:51 -0700
Processing by BillsController#show as JS
Parameters: {"utf8"=>"✓", "congress"=>"112", "bill_type"=>"hr", "bill_number"=>"1027", "commit"=>"Submit"}
Unpermitted parameters: :utf8, :commit
Unpermitted parameters: :utf8, :commit
Unpermitted parameters: :utf8, :commit
Bill Load (0.1ms) SELECT "bills".* FROM "bills" WHERE (congress = '112' AND bill_type = 'hr' AND bill_number = '1027') LIMIT ? [["LIMIT", 1]]
Unpermitted parameters: :utf8, :commit
Called to show!
Completed 200 OK in 2980ms (Views: 0.6ms | ActiveRecord: 0.7ms)
But if the form were to be redirecting to show.html.erb the console output ought to return 3XX, no?
My (evidently wrong) understanding is that when I call the show action in my bills_controller, the website should automatically redirect to the views/bills/show.html.erb page. Why is this not the case, and how can I idiomatically correctly edit my code so that the desired redirect occurs?
Help is much appreciated.
The error was resolved by setting local: true within the form_with tag. Nevertheless, I am unclear as to why
This is from Rails Guides:
"By default form_with submits forms using Ajax thereby skipping full page redirects. To make this guide easier to get into we've disabled that with local: true for now."

Password not filtered in log

According to Rails documentation
config.filter_parameters used for filtering out the parameters that
you don't want shown in the logs, such as passwords or credit card
numbers. By default, Rails filters out passwords by adding
Rails.application.config.filter_parameters += [:password] in
config/initializers/filter_parameter_logging.rb. Parameters filter
works by partial matching regular expression.
So, why when I submit the form below
<%= form_with model: #user, url: admin_user_path, method: :delete do %>
<%= label_tag :password, t('forms.password') %>
<%= text_field_tag :password, nil %>
<%= button_tag t('forms.save'), type: 'submit' %>
<% end %>
I can see my password in the log?
<ActionController::Parameters {"utf8"=>"✓", "_method"=>"delete", "authenticity_token"=>"r22P2Mi1xcWOjRHGogoFaDcOec9/FgkC9btCo66qmqaKG/zwzUkbUGtATsTKV19OOYK80VBf1h0CzFtoRltQOA==", "password"=>"x", "button"=>"", "controller"=>"admin/users", "action"=>"destroy", "id"=>"at-example-com"} permitted: false>
Shouldn't the password be [FILTERED]?
The piece of code you're showing isn't from a log:
<ActionController::Parameters {"utf8"=>"✓", "_method"=>"delete", "authenticity_token"=>"r22P2Mi1xcWOjRHGogoFaDcOec9/FgkC9btCo66qmqaKG/zwzUkbUGtATsTKV19OOYK80VBf1h0CzFtoRltQOA==", "password"=>"x", "button"=>"", "controller"=>"admin/users", "action"=>"destroy", "id"=>"at-example-com"} permitted: false>
That output from the command like puts(params). The option filter_parameters is about log file which placed under log directory. E.g. log/development.log
Here is a piece of log file:
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxQJeccoEATtyCFy1eV", "user"=>{"first_name"=>"Juggy Head", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create user"}
You have used text_field_tag (It's going to input type text) that's why it's showing value in the log you need to use password_field_tag (It's going to input type password) like below
<%= form_with model: #user, url: admin_user_path, method: :delete do %>
<%= label_tag :password, t('forms.password') %>
<%= password_field_tag :password, nil %>
<%= button_tag t('forms.save'), type: 'submit' %>
<% end %>
Rails API doc here
For instance, password filtering to use above code
Update
I completely agree with this answer Зелёный

Rails issue with access of nested hash parameter

I have in rails the following form in a view
<%= form_for (#account) do |f| %>
<%= f.label :comments,"Comments" %>
<%=f.text_area :comments %>
<%= f.submit "Confirm",:name=>"conf" %>
<%= f.submit "Reject" %>
<% end %>
When I submit the form I get the following hash in the log before the update of the database
Started PATCH "/accounts/12" for 127.0.0.1 at 2015-08-13 21:31:18 +0200
Processing by UseractionsController#answer_with_comments as HTML
Parameters: {"utf8"=>"✓", "account"=>{"comments"=>"mycomments"}, "conf"=>"Confirm", "id"=>"12"}
I am trying to access the input in the comments text area in the controller. I tried
params[:account][:comments]
but it does not seem to work. Could anyone give me the appropriate syntax? Thanks.
EDIT
This is my controller code. Right now the if loop return false and nothing is added to the database even though there is something submitted ("mycomments" see above in the param nested hash)
if params[:bankaccount][:comments]
#bankaccount.update_attribute(:comments, params[:bankaccount][:comments])
end
It is only the appropriate syntax for your view. It assumes that you have content field on your Comment model.
<%= form_for (#account) do |f| %>
<%= f.label :comments,"Comments" %>
<%= f.fields_for :comments do |ff| %>
<%= ff.text_field :content %>
<% end %>
<%= f.submit "Confirm",:name=>"conf" %>
<%= f.submit "Reject" %>
<% end %>
You also will have to declare nested attributes in your Account model and your params hash should be different.
You should watch these two Railscasts part 1 and part 2 to learn more about nested attributes.
Since you mention strong parameters as a tag you probably want to build this a bit differently.
private
def account_params
#the permit method might need to be altered depending on your model and view
params.require(:account).permit(:comments)
end
Somewhere else in your controller you would then do:
#bankaccount.update_attributes(account_params)
Please take a read: http://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters

Resources