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 %>.
Related
New web developer here, and I think I may be missing some very fundamental knowledge. Given the code
> def create
> #post = Post.new(post_params)
> if #post.save
> redirect_to #post
> else
> render "new"
> end
end
after saving the post, it redirects to show page, due to this "redirect_to #post", how can I do the same thing with "redirect_to: action => "show", :id => 5" I have to pass the ID now, how to retrieve the ID from #post object?
so only I can pass the Id to redirect page.
can I stop the compiler here, like debugger in js?
To answer your question of "I may be missing some very fundamental knowledge" yes, you might be. An object in Rails like #post is usually a database record. You can access any of it's columns in the DB by using the column name as a method:
#post.id
returns:
5 #or whatever the post id is.
If your post table has a column of "title" you can access it with
#post.title
returns:
"This is an awesome post"
I would highly recommend you view some Ruby and some Rails tutorials. Everything in Ruby is an object. Rails uses a lot of conventions so you can do things without having to write code for it, it's already there for you. When you get into Rails ActiveRecord Relations you'll see that relations expand this to give you related table information as methods. For Example:
Post.rb
...
belongs_to :user
User.rb
...
has_many :posts
Gives you methods like:
#post.user #returns the user object with all of its info
#post.user.username #returns the value of that column for that user
#post.user.posts #returns an array of Post objects that belong to the owner of that post.
Ruby has a pry-byebug gem for debugging. It's a combination REPL (Pry) and core debugger (byebug) that work very powerfully together.
Getting the id of a successfully saved ActiveRecord model is just #post.id, however the rails methods like redirect_to will take the object itself just fine, as #Beartech has mentioned, above. The documentation shows a variety of ways to use it, for convenience:
redirect_to action: "show", id: 5
redirect_to #post
redirect_to "http://www.rubyonrails.org"
redirect_to "/images/screenshot.jpg"
redirect_to posts_url
redirect_to proc { edit_post_url(#post) }
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
#....
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
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.
Update : Gutted entire question with more thorough description
Ok same question with different names.
In my model, I do validate the presence of.
class QuickFact < ActiveRecord::Base
belongs_to :organization
validates_presence_of :quick_fact, :content
But if either is blank, it errors out with :
Missing template organizations/_quick_fact_fields.erb
Here's the catch. I have a nested form model with dynamically addable parts to it. As followed from here :
http://railscasts.com/episodes/197-nested-model-form-part-2
That is what generates and calls the _quick_fact_fields.erb . But that works perfectly and is located within quick_facts/_quick_fact_fields.html.haml
Update: My Controller Code
organizations_controller.rb
def update
if #organization.update_attributes(params[:organization])
..
elsif params[:organization][:quick_facts_attributes]
flash[:notice] = 'QuickFacts successfully updated.'
redirect_to organization_quick_facts_url(#organization)
else
flash[:notice] = 'Organization was successfully updated.'
redirect_to :action => 'edit'
end
else
# re-render last form
..
elsif params[:organization][:quick_facts_attributes]
render :template => "quick_facts/index"
else
render :action => 'edit'
end
end
end
It seems that you're trying to render a my_custom_field partial from one of the worker views found in app/views/worker, but apparently there's no such partial there. If you show us the code of the relevant views and controllers, it will be easier to pinpoint the exact problem.
On a side note, you could simply do validates_presence_of :name instead of defining a custom validation method to simplify your model. However, this is likely unrelated to the error you're describing and is just a general improvement suggestion.
Got it. I had two controllers.
quick_facts_controller.rb, and organizations_controller.rb
Once I deleted the update function in quick_facts_controller, it worked properly.