I have an object Tasks with a model like this
has_many :notes, :validate => true
And Notes with a model like this:
belongs_to :task
validates_presence_of :body, :message => "cannot be empty, bonehead!"
I have a /tasks/new view to create a new task (form _for), and a note for it (fields _for). I want the validation failure messages for the Task and Note to be spat out at the top of the form.
The controller looks like:
def create
#task = Task.new(params[:task])
#note = Note.new(params[:note])
#task.notes << #note
if #task.save
redirect_to tasks_path
else
render :action => 'new'
end
The problem is, when no Note body is entered a validation error message is returned in #note, "Body cannot be blank, bonehead"; and another one in #task, "Note is invalid".
I'm spitting both out in the view like this:
<%= error_messages_for 'task', 'note', 'users_list', :header_message => nil, :message => nil %>
I want to keep the Note model validation message, and not have one as part of the Task object, "Not is invalid".
Thanks a lot!
I don't have a console in front of me, but I think if you change your if statement to if #note.valid? and #task.save it would check the note first and only give you the first message.
Edit: This is just kind of an FYI, but you might want to use build instead of two new statements:
def create
#task = Task.new(params[:task])
#note = #task.notes.build(params[:note])
if #task.save
...
Related
I have a form used to create clients, and in one of the fields I have to choose the language of the client. In the model I have a validation to check the field is not null, but the validation error is getting displayed even when a language is provided.
View:
<%= f.input :locale, as: :select, collection: locale_for_select, prompt: false %>
Model:
validates :locale, presence: true
Controller:
def new
end
def edit
end
def create
if #client.save
redirect_to #client, notice: t_notice('controllers.successfully_created', Client)
else
render action: "new"
end
end
def update
if #client.update_attributes(params[:client])
redirect_to #client, notice: t_notice('controllers.successfully_updated', Client)
else
render action: "edit"
end
end
I have used the browser's developer tools to check the value is actually being send, although the validation at the model fails.
Any idea about what's going on?
EDIT:
I have noticed this error only happens when creating a new client, not while editing an existing one. However, when I edit a client this new value is not being persisted to database
EDIT 2:
Using rails 3.2.22
Using ruby 2.1.6
EDIT 3:
This is strange because in the same form I have some other select inputs that are working properly, and which are treated in a similar way.
def create
#client = Client.new(params[:client])
if #client.save
redirect_to #client, notice: t_notice('controllers.successfully_created', Client)
else
render action: "new"
end
end
def update
#client = Client.find(params[:id])
if #client.update_attributes(params[:client])
redirect_to #client, notice: t_notice('controllers.successfully_updated', Client)
else
render action: "edit"
end
end
The problem was that I had added a localized field using Globalize, and I did not take this into account:
Because globalize uses the :locale key to specify the locale during
mass-assignment, you should avoid having a locale attribute on the
parent model.
What I did to solve this issue is renaming my :locale attribute to :client-locale and execute the corresponding migration to rename the column.
subsriber.rb
class Subscriber < ActiveRecord::Base
validates_confirmation_of :email, :message => "Your emails don't match!"
end
I have this in my rails app. When I create a new record without matching email
Here's my create action:
def create
#subscriber = Subscriber.new(params[:subscriber])
if #subscriber.save
redirect_to root_path, :notice => "You've been subscribed!"
else
render 'new'
end
end
How do I make the error message show up in the view file? I don't see anything in the docs saying I need to add something to my views but the message is not showing up.
You actually do need to add something to your view to show the message.
Rails normally does this for you when you create a scaffold, but if you need to do it manually for a field, you need to add something like this to your HTML template:
<%= f.error_messages_for :email_confirmation %>
I have two models, Character and Initiative, and their relationship is Character has_one Initiative and Initiative belogns_to Character. I'm working on validation for Initiative, and I have it working, but the issue is all of my validation errors appear when creating a new Initiative record for a Character, before entering any information. Any ideas? Here's my code from Initiatives controller:
def new
#character = Character.find(params[:character_id])
#initiative = #character.create_initiative(params[:initiative])
end
def edit
#character = Character.find(params[:character_id])
#initiative = #character.initiative
end
def create
#character = Character.find(params[:character_id])
#initiative = #character.create_initiative(params[:initiative])
if #initiative.save
redirect_to character_path(#character), :notice => "initiative successfully created!"
else
render :action => "new"
end
end
def update
#character = Character.find(params[:character_id])
#initiative = #character.initiative
if #initiative.update_attributes(params[:initiative])
redirect_to character_path(#character), :notice => 'Initiative information was successfully updated.'
else
render :action => "edit"
end
end
And here's the validation itself from my model:
validates_presence_of :dex, :misc, :speed
validates_numericality_of :dex, :misc, :speed
I'm pretty sure the problem lies in the create or new methods, but I'm not sure why it's triggering the validation before a user enters any information. Any help? Maybe not a huge concern, since the code IS working, but I'd rather not display an error message before actually getting an error. Thanks!
shouldn't you be using build_initiative instead of create_initiative in your new action ? no need to save an object when sending to the user a form that intends to create it. Moreover, if your character has_one initiative, he can only have one so i doubt AR appreciates that you try to create another.
see http://guides.rubyonrails.org/association_basics.html#has_one-association-reference
How can you pass an error messages coming from a model --> controller to view?
= form_tag :controller => "article", :action => "create" do
/ how to retrieve error messages here?
%p
= label_tag :article, "Article"
= text_field_tag :article
= submit_tag "Submit Article"
I have this model:
class Article < ActiveRecord::Base
attr_accessible :article
validates :article, :presence => true
end
In my controller:
def create
#article = Article.new(params[:article])
if ! #article.save
# how to set errors messages?
end
end
I'm using Rails 3.0.9
The errors messages are stored in your model. You can access through the errors methods, like you can see in http://api.rubyonrails.org/classes/ActiveModel/Errors.html.
An easy way to expose the error message is including the follow line in your view:
%span= #article.errors[:article].first
But, I belive you have to change your controller to be like that:
def new
#article = Artile.new
end
def create
#article = Artile.new params[:article]
if !#article.save
render :action => :new
end
end
In the new action you don't need to try save the article, because the creation action already do that job. The new action exists, (basically) to call the new view and to provide support for validations messages.
The newmethod shouldn't save anything. create method should.
def create
#article = Article.new(params[:article])
if ! #article.save
redirect_to root_path, :error => "ops! something went wrong.."
end
end
So I'm using the excellent Ancestry gem But while the documentation seems very complete I don't understand how to pass the parameter of my element which I want to be the parent of my newly created element. Firstly, do I want to do it in the new or create action... allow me to explain. For example: (with some actions removed for brevity)
class PeopleController < ApplicationController
#...
def new
#person = Person.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Registration Successful."
redirect_to root_url
else
render :action => 'new'
end
end
end
So namely I don't know where to create the ancestry, the docs say:
...You can use the parent attribute to organise your records into a tree. If you have the id of the record you want to use as a parent and don’t want to fetch it, you can also use parent_id. Like any virtual model attributes, parent and parent_id can be set using parent= and parent_id= on a record or by including them in the hash passed to new, create, create!, update_attributes and update_attributes!. For example:
TreeNode.create! :name => 'Stinky', :parent => TreeNode.create!(:name => 'Squeeky')
I want to know what my controller show look like to allow me to set the parent of the #person when I create them.
So otherwise I'm stuck, I don't know what else to do here... but anyhow, I do know that this gem is similar to the more popular acts_as_tree, any help is super appreciated!
Updated
I think I almost have it but when I try this for my create action
def create
#parent = Recipe.find(params[:parent])
#recipe = Recipe.new(params[:recipe], :parent => #parent.id) do |recipe|
recipe.user_id = current_user.id
end
if #recipe.save
current_user.has_role!(:owner, #recipe)
redirect_to #recipe
else
render :action => 'new'
end
end
I get:
Couldn't find Recipe without an ID
Updated
My view has a link to the new action that looks like this <%= link_to "fork this recipe", {:controller => "recipes", :action => "new", :parent => #recipe} %>
That seems to look fine to me, also the url reads fine when you get to the form, recipes/new?parent=112, but I still get that error, there has to be a way for that parameter to be passed as the parent of the newly created object.
If it works like acts_as_tree then I'll assume that you can do something like this:
#parent.children.create(attributes)
Which will create a new child object with the parent set, regardless of what the attributes say.
According to the docs that you pasted you can do:
#...
#user = User.new(params[:user])
#user.parent_id = #parent_user.id
#user.save
#...
You can also include it in the params hash for the user -- your form submission would need to have params[:user][:parent_id]:
#user = User.create(params[:user])