atmorell
(atmorell)
August 24, 2008, 6:35pm
1
Hello,
I got a form that feeds data to 2 models: Topic and Post.
@topic = Topic.new(params[:topic])
@post = Post.new(params[:post])
if @topic.save
@post.topic_id = @topic.id
@post.save
end
Now if there is an error in the Topic data RoR will catch it. But if
the Post fails validation the Topic still gets created. So what would
like to do is doing a test on each object and then save.
Did google the topic but did not hit the nail on the head.
Best regards.
Asbjørn Morell.
Hello,
I got a form that feeds data to 2 models: Topic and Post.
@topic = Topic.new(params[:topic])
@post = Post.new(params[:post])
if @topic.save
@post.topic_id = @topic.id
@post.save
end
Now if there is an error in the Topic data RoR will catch it. But if
the Post fails validation the Topic still gets created. So what would
like to do is doing a test on each object and then save.
Just call the valid? method
Fred
atmorell
(atmorell)
August 24, 2008, 7:19pm
3
Hmmm just gave it a try:
if @post.valid ? and @topic.valid ?
@topic.save
@post.topic_id = @topic.id
@post.save
end
The "if" condition does not seem to care about the Post validation.
Topic validation works as it should
Any ideas?
atmorell
(atmorell)
August 24, 2008, 9:20pm
4
Problem solved. valid? was the method I was looking for.
Thanks.
fxn
(Xavier Noria)
August 24, 2008, 9:40pm
5
You could for example add
validates_associated :topic
to the Post model and then:
post = Post.new(params[:post])
post.build_topic(params[:topic])
if post.save
# both post and topic are valid
else
# at least one of them is invalid, you got all errors in one shot
end
That said, in AR I normally work from the parent downwards:
topic = Topic.new(params[:topic])
topic.posts.build(params[:post])
topic.save
In any case, if the associated object is invalid you have an error in
the "root" object telling so, and the particular errors in the child.
fxn
(Xavier Noria)
August 24, 2008, 9:42pm
6
I forgot to mention in that alternative you put
validates_associated :posts
in the Topic model.
Watch out: "and" is not the same as "&&"
if @post.valid ? and @topic.valid ? # equivalent to @post.valid ?; if
@topic.valid ?
See http://www.pjhyett.com/posts/201-using-or-and-in-ruby for more
details.
I think you really just want a transaction here. If you don't want
the Topic created when the post fails, you can do the following:
Post.transaction do
@topic = Topic.new(params[:topic])
@post = Post.new(params[:post])
if @topic.save
@post.topic_id = @topic.id
@post.save
end
end
If one fails, all fail and you don't get the unwanted saves.
-Kevin
fxn
(Xavier Noria)
August 26, 2008, 3:44pm
9
Problem is if @topic.save fails and @post is invalid you are not able
to show @post 's validation errors to the user in the same view.