When using strong_params and getting an ActiveModel::ForbiddenAttributesError exception, how do I find out which attribute is forbidden? I've just switched from attr_accessible and the debug message was normally pretty good there but not when switching to strong params.
I receive this error:
ActiveModel::ForbiddenAttributesError in SnippetsController#create
This is a nested model.
def snip_params
params.require(:snippet).permit(:content, :approved, :user_id, :book_id)
end
In the parent I've used
has_nested_attributes :snippets
The create
def create
#snippet = #book.snippets.create(snip_params)
#snippet.user = current_user
if #snippet.save
redirect_to #book
flash[:success] = "Snippet submitted and awaiting approval."
else
flash[:base] = "Someone else has submitted a snippet, please try again later"
redirect_to #book
end
end
Params Contents:
{"utf8"=>"✓",
"authenticity_token"=>"bTRSwFRIhN3l3DkkWPtLzpoQHYD+CezmJQLw8Oz5+3g=",
"snippet"=>{"content"=>"<p>AAAAAAAAAAAAA</p>\r\n"},
"commit"=>"Create Snippet",
"book_id"=>"1"}
All attributes are forbidden initially. This exception is only raised when you don't permit any attributes. If you permit some and not others, then the log output tells you which parameters were not permitted.
params = ActionController::Parameters.new(name: 'Bob', age: 24)
#params are usually set automatically in the controller
Person.new(params)
The above will raise the exception
Person.new(params.permit(:name))
This will create a person with name 'Bob', the log output will also contain:
Unpermitted parameters: age
They are logged into DEBUG level: https://github.com/rails/strong_parameters/blob/master/lib/strong_parameters/log_subscriber.rb
Related
Here i'm trying to save json data to sqlite database using rails controller, but i'm not getting json data to controller parameters
In a specific controller I have the below list of params:
Parameters: {"person"=>"{\"name\":\"akhil\",\"profession\":\"it\",\"address\":\"hyderabad\",\"mobilenum\":67588}"}
Controller
def createPerson
puts "parameters are : "+params[:person].to_s
user_params = ActiveSupport::JSON.decode(params[:person])
puts "parameters name:"+user_params[:name].to_s
#person = Person.new(name: user_params[:name], profession:
user_params[:profession], address: user_params[:address], mobilenum:
user_params[:mobilenum])
#person.save
end
It is showing below error
(no implicit conversion of nil into String)
I'm getting the nil value in user_params[:name].to_s
Could you please help me to solve this
Seems like all you need to do is to create a new Person record after submitting a form. Well, probably you would want to use strong params and make a little refactor, so your controller will look something like this:
class PersonsController < ApplicationController
# you can name your action simply `create`, so you can use resource routing
def create
# most probably you don't need to make person an instance variable
person = Person.new(person_params)
# and here it is a good practice to check if you really saved your person
if person.save
# do something to tell user that the record is saved, e.g.
flash[:success] = 'person has been saved'
else
# show user why your person record is not saved, e.g.
flash[:error] = "person cannot be saved: #{person.errors.full_messages.to_sentence}"
end
end
private
# and here is the method for your permissible parameters
def person_params
params.require(:person).permit(:name, :profession, :address, :mobilenum)
end
end
Controller:
def foo
redirect_to home_path(params: auth_params)
end
private
def auth_params
params.require(:auth).permit(:name, :email, :photo_url, :provider, :provider_id)
end
Here are the parameters that the controller errors out on:
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"...",
"auth"=>
{"name"=>"...",
"email"=>"...",
"photo_url"=>"...",
"provider"=>"...",
"provider_id"=>"..."}
}
With this error: unable to convert unpermitted parameters to hash
I permit all the params (with the exception of the rails default params (i.e. utf8, authenticity_token, so why is this error popping up?
EDIT:
Neither of the following suggestions are working either:
redirect_to home_path(auth_params)
redirect_to home_path, params: auth_params
A little more info on how I get to the controller action might help:
I have (in the same controller) an action bar that has a form_tag in the view that goes to foo_path. I've tried submitting the form via jQuery or a submit button, it doesn't change the result. As soon as I hit the auth_params method I get the error.
This means it is erroring out on the auth_params method rather than the redirect itself
I have get this error too when I have upgrade to Rails 5.1.4. I fixed with this
redirect_to(home_path, params: params.require(:auth).permit(:name, :email, :photo_url, :provider, :provider_id))
I hope this help you.
After I restarted the development server AND cleared all the cookies placed by rails (most notably the app-name session cookie), the normal strong parameter syntax (i.e. params.require().permit()) works fine.
The home_path and other url_for related methods are expecting a Hash object instead of an ActionController::Parameters object (which is what the params method in controllers returns) so you need to convert it to a hash first, like so:
redirect_to home_path(auth_params.to_h)
You´re doing it very wrong. If you are creating a resource then you should reply to validation errors by rendering a view - not redirecting.
The response you´re sending the user is the result of performing a non-idempotent action.
This might seem like nitpicking but outing the users email & chosen password in the GET parameters is pretty reckless.
If you are embedding a form in your homepage its pretty simple to just create a auths/new.html.erb view which just shows the form and lets the user correct the misstakes:
class AuthsController
def create
#auth = Auth.new(auth_params)
if #auth.save
redirect_to some_path, success: "Your account was created"
else
render :new
end
end
private
def auth_params
params.require(:auth).permit(:name, :email, :photo_url, :provider, :provider_id)
end
end
If the form has to be seamlessly included in the home page then you need to render that view or use ajax to perform it in place.
I am new to rails and am in the process of entering in information in a form and saving it to a database. I am following a tutorial which may be out of date. I am getting an error on the second line. Am I passing the wrong parameter?
def create
#student = Student.new(params[:student])
if #student.save
redirect_to new_student_path
end
end
I expect the problem is that you need to process the student parameters before passing them to Student.new, so as not to fall foul of the strong parameters system.
Try this:
def create
#student = Student.new(student_parameters)
if #student.save
redirect_to new_student_path
end
end
private
def student_parameters
params.require(:student).permit(:name, :age)
end
replace :name, :age with the list of attributes you want to white list (allow through)
More information about the mass assignment vulnerability that strong parameters mitigates can be found here.
When I try to create a user, Rails returns a ParameterMissing error:
ActionController::ParameterMissing in UserController#create
param is missing or the value is empty: user
My Controller
class UserController < ApplicationController
def create
#user = User.new(user_params)
render json: #user
end
private
def user_params
params.require(:user).permit(:fame, :lame, :mobile)
end
end
My User Model
class User < ActiveRecord::Base
self.table_name = "user"
end
What am I doing wrong?
Check your logs for the params that are being sent to your controller. Most likely, the params hash being sent by your view doesn't include the :user, key. To fix, you'll need to make sure your form_for is properly namespaced with a User object:
form_for #user do |f|
# ...
end
You can also use the as key to explicitly set the :user key in your params.
form_for #object, as: :user, method: :post do |f|
# ...
end
Update
Since the questioner was using postman to send data, the data sent to the server should be properly formatted like so:
user[firstName]
Thanks #Fabio and #Anthony
When you asked about the form, I actually realized that the parameter I sending with postman was actually incorrect as they should be like
user[firstName]
Updated
It actually deepns upon you how you send the params.
I send as
user[firstname] So I get like params[:user][:firstName]
If I send like firstname So this will be params[:firstName]
I've got a very simple app where the flow looks like this:
User reads some copy, decides they want to purchase the product and fill out the form, see confirmation page.
Something is wrong in my controller but I can't quite pinpoint it where I'm getting the error Couldn't find Customer without an ID.
class CustomersController < ApplicationController
# before_filter :load_customer, :only => :show
def new
#customer = Customer.new
end
def create
#customer = Customer.new(params[:customer])
if #customer.save
session[:customer_id] = #customer.id
purchase
else
flash[:error] = "Please enter a valid email address"
redirect_to :signup
end
end
def signup
#customer = Customer.new
end
def purchase
Stripe.api_key = STRIPE['secret']
charge = Stripe::Charge.create(
:amount => 2000,
:currency => "usd",
:card => params[:stripe_token],
:description => "My Product Name"
)
redirect_to receipt_path
end
def receipt
#customer = Customer.find(session[:customer_id])
#name = #customer.name
#email = #customer.email
#product = #customer.product
end
# private
#
# def load_customer
# #customer = Customer.find(session[:customer_id])
# redirect_to request.path.gsub(params[:id], session[:customer_id].to_s) if params[:id] != session[:customer_id].to_s
# end
end
I'm not sure where things are screwing up and after much Googling, I'm turning to you guys. Help would be huge.
EDIT:
Consulting with Rails console shows that my application isn't making new customer records for some reason. Charging is working, however. Customers not being created must be a precursor to this.
EDIT 2: Development.log
Started GET "/assets/bootstrap.js?body=1" for 127.0.0.1 at 2012-08-28 15:58:11 -0700
Served asset /bootstrap.js - 304 Not Modified (0ms)
[2012-08-28 15:58:11] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
Started POST "/checkout" for 127.0.0.1 at 2012-08-28 15:58:12 -0700
Processing by CustomersController#purchase as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"k2aW/CAkNfwDSMHHvzbuOwm+Xua0qb2LJ4LtrtRvyvk=", "customer"=>{"name"=>"Your name", "email"=>"yourname#example.com"}, "stripe_token"=>"tok_0GUvwKPwo6jfEu"}
Redirected to http://localhost:3000/receipt
Completed 302 Found in 1064ms (ActiveRecord: 0.0ms)
Started GET "/receipt" for 127.0.0.1 at 2012-08-28 15:58:14 -0700
Processing by CustomersController#receipt as HTML
Completed 500 Internal Server Error in 0ms
ActiveRecord::RecordNotFound (Couldn't find Customer without an ID):
app/controllers/customers_controller.rb:38:in `receipt'
Rendered /Users/zack/.rvm/gems/ruby-1.9.3-p194#beat-the-herd/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (3.9ms)
Rendered /Users/zack/.rvm/gems/ruby-1.9.3-p194#beat-the-herd/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (5.6ms)
Rendered /Users/zack/.rvm/gems/ruby-1.9.3-p194#beat-the-herd/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (23.7ms)
If the user routes directly to receipt action then session[:customer_id] may be nil. That's why you get the error. This is not happened if a create (possibly) POST request is issued. In this case, the session variable has been populated before the redirection to the receipt action.
This line :
#customer = Customer.find(session[:customer_id])
throws an error because session[:customer_id] is nil
You might want to use find_by_id that won't throw an Exception but will return an nil record.
Then you'll have to deal with the case of #customer being nil.
Add this in UserController
def show <br>
#user = User.find(session[:user_id])<br>
#profile = #user.profile<br>
end
Rather than putting "user_id" put session[:user_id]
It worked for me