Rails 4: How to check validation errors from inside a controller - ruby-on-rails

I have some basic model validations that are triggered when a form gets submitted by AJAX. If the validations fail, I want to pass the validation errors back to the view so I can tell the user.
def save
logger.debug( params )
#video = Video.new( video_params )
if #video.save
render json: #video
else
render json: errors.messages
end
end
This throws an error because errors is undefined. What am I doing wrong? I read the docs on this and it only shows errors.messages used in the view.

errors is a instance method from an ActiveRecord. The correct way to use in your case is like this:
#video.errors.messages

instead of messages use full_messages, like below
#video.errors.full_messages

Related

How to pass objects from one controller to another controller

On an unsuccessful save, I would like to redirect to the previous view but with the error message.
redirect_to user_path(#user_id), errors: #user.errors
but in the view, when I check for errors I get an undefined variable errors.
I am not using the same controller new and create, so I can't have #user.errors.any in new.html.erb. I have two different controllers, one in which form is there, and another controller which will take care of create, if the create is not happening I need to redirect to the previous controller.
You may need to use render instead of redirect_to.
Something like this:
# controller_1
def step_1
#user = User.new
#user.do_something
...
end
# controller_2
def step_2
if #user.save?
# redirect to another...
else
render 'controller_1/step_1`
end
end
Then on view step_1.html.erb, you can print out errors of #user with #user.errors.
You have to pass the parameters inside the redirect_to helper like below,
redirect_to user_path(id: #user_id, error: #user.errors.messages)
Please check the rake routes and pass the appropriate key for id, whether it's :id, or :user_id

Ruby redirect to same page and show errors if form input is bad

Forgive me I'm new at Ruby. I am trying to create a site to contain information about a zoo.
I have an enclosure model and an animal model.
This is my code for the create method in animal_controller
def create
if params.has_key?(:enclosure_id)
#enclosure = Enclosure.find(params[:enclosure_id])
#animal = Animal.new(animals_params)
#animal.user_id = current_user.id
if #animal.save
#enclosure.animals.push(#animal)
redirect_to enclosure_path(#enclosure)
else
# ????
end
else
#animal = Animal.new(animal_params)
#animal.user_id = current_user.id
if #animal.save
redirect_to #animal
else
render 'new'
end
end
end
I then have two places where a new animal can be created. One is using a form at localhost:3000/animals/new. The other is using a similar form on the show page of a particular enclosure, so for example at localhost:3000/enclosures/1/
In my code above, I check for the presence of enclosure_id to determine where the call is coming from. If the parameter is found, I add the animal to the enclosure there and then. However, if #animal.save fails, I do not understand how I can return to the localhost:3000/enclosures/id page with the validation error messages being passed. In the case of no enclosure_id, render 'new' takes the user back to the ../animal/new page with error messages passed as well.
Thanks
I don't think it's a good idea to go to an other page, because you will have to serialize errors linked to the model and it's gonna be complicated and ugly.
I think you should render the show page of the enclosure and then display the errors
#....
if #animal.save
#enclosure.animals.push(#animal)
redirect_to enclosure_path(#enclosure)
else
render 'enclosures/show'
end
#....

Rationale behind render :new instead of redirect_to new for POST create?

Given a rails RESTful controller
class WidgetsController
def new
#widget = Widget.new
end
def create
#widget = Widget.new(params[:widget])
render :new and return unless w.save
redirect_to widget_path(#widget)
end
end
Other than to capture the parameters and render validation messages why is the convention to render :new instead of redirect_to new_widget_path if validation fails?
As URL will alter from /widgets/new to /widgets if validation fails doesn't this break the concept of REST?
Render will not call the controller action, so the instance variables that you have set in the create action will be taken to the new view.
this means that any validation errors persist in the new view...
redirect_to would run the controller action for new, and therefore create a new instance of your model... and you would loose the errors...
hope this helps
Could you do this instead of rendering the new action?
flash[:thing] = params[:thing]
redirect_to new_thing_path
Then in new
#thing = Thing.new(flash[:thing] || params[:thing])
This honestly seems nicer to me because otherwise if you have any logic in your controller that is required to render the new/edit actions, you have to repeat that logic (or create some before_filter or something) in update/create. I realize this involves one more request but aside from that it seems simple and safer to code (apart from the fact that you are breaking rails conventions) and it gives the user a valid url that is always the same for looking at/doing the same thing.
If they refresh they'll lose their values but that is true of any form before being submitted. And that seems to make more sense to me than refreshing resulting in a resubmit warning which is pretty strange. How is a user supposed to clear the form for example?
This rails-ism has always bugged me. Are there are any serious issues with this that I'm not considering? Do other application frameworks all do the same?
The thing with render is that it will not cause another request to be generated. It will go to the corresponding view and display it. With redirect, however, a redirect request to the browser will be generated, which will cause another request to your server.

How do I make form_for to complete with the previously submitted data when validation fails?

Given that I have a large form
When the user submits it
And the validation of the data fails
Then the user is redirected to the previous page again
And the form should contain the data that the user previously submitted
How can I achieve the last part? :P
There is something like flash[] for the form_for helper?
I have to use AJAX?
As some of the comments have suggested, this can be the default behavior, if you're using best practices.
Here's an example of the new/create controller actions that should exhibit said behavior:
def new
#model = MyModel.new
end
def create
#model = MyModel.new(params[:my_model])
if #model.save
redirect_to my_models_url, :notice => "Success!"
else
flash.now[:error] = "There was an error"
render :new
end
end
Check in your view if request.method == :post, and if it is then use the data in params[] instead. It will contain the data you just posted.

How to display error message on model in rails

I need to display error message on model in rails,
my coding on model is like this,
if my_address.valid?
# I need here the validation error.
return nil
end
I used errors.add("Invalid address") but it is not working
please help to solve this problem ,
You will be able to access the errors via object.errors, i.e. for your case my_address.errors. It will return Error objects, you can check up on it here: http://api.rubyonrails.org/classes/ActiveRecord/Errors.html
I suggest taking a look at how scaffolds (script/generate scaffold my_model) displays validation errors.
Here's a short summary:
def create
#post = Post.new(params[:post])
if #post.save # .save checks .valid?
# Do stuff on successful save
else
render :action => "new"
end
end
In the "new" view, you'll use #post.errors, most likely with <%= error_messages_for :post %>.

Resources