Hi,
I recently gathered guts and tried implementing the Rails 2.0.2 in one
of my existing application that was running on Rails 1.2.3. I ran in to
a strange issue.
I have a model <strong>Post</strong> and a model
<strong>Comment</strong>. They have the very general has_many and
belongs_to relationship. Now when I try to implement a join b/w the two
models.
<code>
Post.rb
class Post < ActiveRecord::Base
has_many :comments
end
Comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
end
</code>
Now when I try to do a
<code>
post = Post.find(:first, :joins=>["p LEFT OUTER JOIN comments c ON
p.id=c.post_id"], :select=>["p.id as post_id, c.id as comment_id, p.body
as post_body and c.body as comment_body"])
</code>
It throws me a
<code>
ActiveRecord::ConfigurationError (Association named 'u LEFT OUTER JOIN
comments c ON p.id=c.post_id' was not found; perhaps you misspelled
it?):
</code>
You used to be able to pass an array to :joins, if you do that now it will interpret it as a list of association names (eg :comments etc...) Pass a string if you don't want that to happen.
post = Post.find(:first, :joins=>["p LEFT OUTER JOIN comments c ON
p.id=c.post_id"], :select=>["p.id as post_id, c.id as comment_id, p.body
as post_body and c.body as comment_body"])
post = Post.find(:first, :joins=>["p LEFT OUTER JOIN comments c ON
p.id=c.post_id"], :select=>["p.id as post_id, c.id as comment_id, p.body
as post_body and c.body as comment_body"])
Also, this is more commonly written:
post = Post.find :first, :include => :comments
Let Rails worry about the join for you...
Thanks for your immediate reply Mark Bush. I could have used the
:include attribute of the find method but I wanted only the selected
columns to load due to performance issues. Hence the question.
You used to be able to pass an array to :joins, if you do that now it
will interpret it as a list of association names (eg :comments etc...)
Pass a string if you don't want that to happen.
Fred
Fred,
Thanks for the immediate reply. The fix that you mentioned worked great.
It is strange though why this sudden change in direction. There was
always the include that could be used to eager load the associated
models. Did the Core team market this change? Think it was something I
missed or was using it the way it was not meant to be used from Version
1.2.3!. Any ways thanks once again.
will interpret it as a list of association names (eg :comments
models. Did the Core team market this change? Think it was something I
missed or was using it the way it was not meant to be used from
Version
1.2.3!. Any ways thanks once again.
:joins doesn't eager load: it just creates the join statements for you.
Fred
Hi Fred,
Thanks for the immediate response again. I am aware of the fact that the
joins attribute of the find method generates a join query. But the point
that I was trying to make in my reply to you was that earlier(referring
to Rails 1.2.3 that I last used) the :joins accepted an array but like
you pointed out very rightly that joins did not accept array come Rails
2.0 onwards and only accepted string. This was bit strange to me. I mean
this was not mentioned in the docs. Was joins never expected to accept
an array? Was I doing it all wrong all the way?
will interpret it as a list of association names (eg :comments
models. Did the Core team market this change? Think it was
something I
missed or was using it the way it was not meant to be used from
Version
1.2.3!. Any ways thanks once again.
:joins doesn't eager load: it just creates the join statements for
you.
Fred
Hi Fred,
Thanks for the immediate response again. I am aware of the fact that
the
joins attribute of the find method generates a join query. But the
point
that I was trying to make in my reply to you was that
earlier(referring
to Rails 1.2.3 that I last used) the :joins accepted an array but like
you pointed out very rightly that joins did not accept array come
Rails
2.0 onwards and only accepted string. This was bit strange to me. I
mean
this was not mentioned in the docs. Was joins never expected to accept
an array? Was I doing it all wrong all the way?
Doesn't look like it was ever documented to accept an array. The rdoc
in 1.2.3 says 'An SQL fragment for additional joins like "LEFT JOIN
comments ON comments.post_id = id". (Rarely needed)'. The old
implementation just happened to work if you passed an array with a
single element.