Validates_presence_of :parent_id stopping save

Hi. I’m using rails 2.3.4 and have this association between two of my
models.

Question
has_many :gradings

Grading
belongs_to :question

Grading has this validation:
validates_presence_of :question_id

And this validation test is stopping me from doingg this, which i would
normally expect to work

@question = Question.new(attributes)
@grading = @question.gradings.build(more_attributes)
@question.save #fails because grading has no question_id

Now, i thought that this would work ok because (in my understanding) the
question is saved and then it saves it’s built associated objects. How
can i ensure this will work? Do i need to drop the validation? I’d
rather not if possible.

Grateful for any advice - max

Hi,

I’m not sure 100% what you’re trying to do but the presence of
question_id
will not be there until the record has been saved. No?

And I’m not sure why you’re doing this … @grading =
@question.gradings.build(more_attributes)

Shouldn’t you have done a build before presenting your form if you have
nested forms?

Maybe you could teach me something on what you’re trying to do.

On 13 March 2010 16:54, Max W. [email protected] wrote:

validates_presence_of :question_id
can i ensure this will work? Do i need to drop the validation? I’d
To unsubscribe from this group, send email to
[email protected][email protected]
.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.


100% naturally selected. 0% designed.

I’d say the best way to deal with this is never validate for a
association_id

#validates_presence_of :question_id
validates_presence_of :question

would be better.

if grading.question_id is nil then grading.question will also be nil.
So you’re effectively doing the same check.

I hope this helps

RobL

On 13 March 2010 15:54, Max W. [email protected] wrote:

validates_presence_of :question_id
can i ensure this will work? Do i need to drop the validation? I’d
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.


Rob L.
[email protected]

Hi Anthony, thanks.

I’m not using the rails-supplied nested attributes methods here, though
maybe i should. I’m effectively hand-rolling my own, so i create a
question and some associated objects (eg a grading in this case) at the
same time, from a single form. When i drop the validation on
Grading#question_id then it works fine. I’m just a little puzzled about
the best way to go about validating question_id, since the default way
seems to stop me building a question and gradings at once.

Rob L. wrote:

I’d say the best way to deal with this is never validate for a
association_id

#validates_presence_of :question_id
validates_presence_of :question

would be better.

Hi Rob!

I played with this already, and got a surprising result:

@question = Question.new(attributes)
=>

@grading = @question.gradings.build(other_attributes)
=>

@grading.question
=>nil

This surprised me because i thought that the use of build set up the
association both ways, ie in both objects, so that even though @grading
had no question_id it ‘knew’ that it was associated with @question. I
must admit that this aspect of rails (ie associations that have been
built but not saved yet) is something that i’ve always found a bit
magical and hence unpredicatable.

I don’t have your original mail and am not sure of the model but
question_id
is a foreign key.No? You are checking for the existence of it before it
has
been created, that is why it’s failing, no?

validate methods validate the data before its saved. Unless I’m missing
something from your original query.

Also, build will only build the object without saving it.

So I think you are thinking something should be happening when it’s not.

But I’m quite new to ruby/rails and although I’m developing an
application
and trying to learn at the same time, it’s difficult to grab all the
nuances
of Rails. There’s a lot to learn to become proficient.

On 14 March 2010 22:26, Max W. [email protected] wrote:

Posted via http://www.ruby-forum.com/.


100% naturally selected. 0% designed.

paul h wrote:

Hi Max,

Have you tried:

@question = Question.create(attributes)
@grading = @question.gradings.build(more_attrs)

Using create instead of new will save the Object to the DB first, and
hence:

Hi Paul. Yes, i know that, thanks - in this situation i would do
gradings.create rather than gradings.build. One of the advantages,
though, of using build is that you can do it before the parent has been
saved, and when the parent is saved it will save the child as well.

In general, i try to stick to the standard controller code as much as
possible, which means setting the child gradings through a set method
which will be called by .update_attributes. This is a nice approach as
it means no changes to the standard controller code is required. When i
drop the validation on Grading#question_id (or Grading#question) then it
works fine. My question was really about the behaviour of the unsaved
child objects, and whether they ‘know’ they have a parent. It seems
they don’t.

Hi Max,

Have you tried:

@question = Question.create(attributes)
@grading = @question.gradings.build(more_attrs)

Using create instead of new will save the Object to the DB first, and
hence:

@question[:id] will/should/may not be nil when building your gradings.

I’m six months in to Rails, don’t use build, and haven’t needed to use
any validation yet - am currently extending the generator for my
current and future Apps, so I have held fire on my first app until I
get this completed, but if your only issue is that the FK question_id
requires @question[:id] to exist, then unless I’m mistaken(which I
could be), using create over new should work…

HTH

Paul