Reputation: 5965
I have a controller with the following methods
def create
@todo = Event.new(event_params)
...
end
def event_params
form_params = [:title, :type, :owner_id, :note, :occurred, :due]
form_params[:due].strftime!("%Y-%m-%d")
params.permit(form_params)
end
I found that when I post a date (:due or :occurred) to the create method with a format of mm/dd/yyyy instead of dd/mm/yyyy I'm getting an argument out of range for a date such as 10/30/2014. So I'm trying to convert the date values in the parameters before it calls Event.new
The line - form_params[:due].strftime!("%Y-%m-%d") - is not working and after quite a bit of googling, I can't seem to figure out the right way to modify the value of a parameter. The error I get currently for that line is "no implicit conversion of Symbol into Integer". How can I do this? Thanks.
Upvotes: 1
Views: 3197
Reputation: 645
Super late to the game but you may consider using this gem: github.com/launchpadlab/decanter
It allows you to easily define how incoming params should be parsed.
More on it here: https://medium.com/launchpad-lab/the-missing-step-in-rails-controllers-82aaa9172165
Upvotes: 0
Reputation: 3438
Well, let's discuss each line of your code to make it clear where the mistake is.
form_params = [:title, :type, :owner_id, :note, :occurred, :due]
First, you declare an array of symbols and assign that array to form_params
variable. It's just a simple plain array, not an associative one, so you can access its values using indexes only, e.g. form_params[0]
would return :title
, but form_params[:due]
is a runtime error as :due
is not an integer index.
Actually, the purpose of event_params
method should be as simple as stating which parameters you allow to be mass-assigned to your objects, so it should look like
params.permit([:title, :type, :owner_id, :note, :occurred, :due])
Getting further, your aim is to edit parameters which came from client-side. As of various dates formats parsing, please refer to this topic.
Disclaimer: It could be much more elegant to force users to pass due
date in conventional %Y-%m-%d
format. Please give a look to rails dates helper methods.
That parameters reside in params
hash, so you could rewrite appropriate key:
def event_params
params["due"] = Date.strptime(params["due"], "%m/%d/%Y").to_s
# here we've converted date format to standard %Y-%m-%d
params.permit([:title, :type, :owner_id, :note, :occurred, :due])
end
This should do two things:
due
with appropriate date formatAnd the rest of your code should work fine with this correction:
def create
@todo = Event.new(event_params)
...
However, beware of side effects:
event_params
restricts you from getting actual %m/%d/%Y
user input now.%m/%d/%Y
formatted date and it would end in runtime error. Upvotes: 2
Reputation: 475
You are assigning form_params an array of symbols, and you can't reference an element of an array by symbol, thus your error. You probably want that to look like this:
form_params = params.permit(:title, :type, :owner_id, :note, :occurred, :due)
which will give you the hash you are looking for.
Edit: at first I didn't check the date manipulation you were attempting. You would need to use Date.strptime to convert your string to a date, but you need to know the date format. Unfortunately, you cannot accurately guess that type of thing. If you know the date will be mm/dd/yyyy, you could convert formats like this:
params[:due] = Date.strptime(params[:due], '%m/%d/%Y').strftime("%Y-%m-%d")
Upvotes: 1