AR Associations- Am I missing something?

I am doing a pilot eval of Rails for my company. We’re using it to build
a reporting module on top of a mysql database which is currently
populated by a ASP.NET application.

One thing I am wondering about is the utility of ActiveRecord
associations, and whether I am missing some simple trick in their use.

Assume I have a User and a Post. Users can have many posts, and Posts
have characteristics like a datestamp, rating, word count, deleted flag,
etc.

While it is beautifully easy to do john.posts and get all of John’s
posts, what I almost always need to do is get john.posts(not_deleted and
post_date=today) or something like that.

Granted, I’ve figurd out how it can be done e.g. Posts.find(john,
not_deleted, date…) but by the time I’m done it seems like all I’m
getting from ActiveRecord is a less top-heavy interface for SQL result
sets, which is a nice thing for sure. But, I’m feeling a bit let down as
the need to select associated objects with conditions beyond just the
association is pervasive, which means I am back to writing lots of
get_foo methods and doing sql construction.

Any thoughts or suggestions?

Cw K. wrote:

While it is beautifully easy to do john.posts and get all of John’s
posts, what I almost always need to do is get john.posts(not_deleted and
post_date=today) or something like that.

You can define a :conditions attribute when you find associated objects,
or on the association call itself.

john.posts.find(:all, :conditions => [‘not_deleted = ?’, true])

Or even better

class User < ActiveRecord::Base
has_many :posts,
:conditions => [‘not_deleted = ?’, true]

has_many :all_posts,
         :class_name => 'Post',
         :foreign_key => 'user_id'

end

This way john.posts will always conform to the defined conditions. And
if you want all posts, regardless of not_deleted status, you can call
john.all_posts. Just note that you have to tell it the class_name and
foreign_key of the association since it can’t be directly inferred form
“all_posts”.

Alex- thanks for that tip, that fills in some big gaps. However, I ran
into one snafu:

Alex W. wrote:

Cw K. wrote:

While it is beautifully easy to do john.posts and get all of John’s
posts, what I almost always need to do is get john.posts(not_deleted and
post_date=today) or something like that.

You can define a :conditions attribute when you find associated objects,
or on the association call itself.

john.posts.find(:all, :conditions => [‘not_deleted = ?’, true])

When I try this I get an error: ArgumentError: wrong number of arguments
(2 for 1)

The method below however works fine :slight_smile:

Or even better

class User < ActiveRecord::Base
has_many :posts,
:conditions => [‘not_deleted = ?’, true]

has_many :all_posts,
         :class_name => 'Post',
         :foreign_key => 'user_id'

end

This way john.posts will always conform to the defined conditions. And
if you want all posts, regardless of not_deleted status, you can call
john.all_posts. Just note that you have to tell it the class_name and
foreign_key of the association since it can’t be directly inferred form
“all_posts”.

class User < ActiveRecord::Base
has_many :not_deleted_posts, :class_name => “Post”, :conditions =>
“not_deleted is true”
has_many todays_post, :class_name => “Post”, :conditions => “date =
today”
end

Is this what you’re looking for ?

Thanks,
Pratik

On 11/19/06, Cw K. [email protected] wrote:

etc.
association is pervasive, which means I am back to writing lots of
get_foo methods and doing sql construction.

Any thoughts or suggestions?


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


rm -rf / 2>/dev/null - http://null.in

Dont judge those who try and fail, judge those who fail to try…

Hi –

On Sun, 19 Nov 2006, Alex W. wrote:

Cw K. wrote:

While it is beautifully easy to do john.posts and get all of John’s
posts, what I almost always need to do is get john.posts(not_deleted and
post_date=today) or something like that.

You can define a :conditions attribute when you find associated objects,
or on the association call itself.

john.posts.find(:all, :conditions => [‘not_deleted = ?’, true])

If you’ve defined not_deleted as a boolean column you should also be
able to do:

:conditions => “not_deleted”

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

On 11/19/06, Alex W. [email protected] wrote:

Just note that you have to tell it the class_name and
foreign_key of the association since it can’t be directly inferred form
“all_posts”.

foreign_key won’t be necessary if it’s user_id.

-Pratik


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


rm -rf / 2>/dev/null - http://null.in

Dont judge those who try and fail, judge those who fail to try…

Hi –

On Mon, 20 Nov 2006, Cw K. wrote:

You can define a :conditions attribute when you find associated objects,
or on the association call itself.

john.posts.find(:all, :conditions => [‘not_deleted = ?’, true])

When I try this I get an error: ArgumentError: wrong number of arguments
(2 for 1)

Whoops, I didn’t spot that problem when I advised about not bothering
with the " = ?', true" part :slight_smile:

The method below however works fine :slight_smile:

Or even better

class User < ActiveRecord::Base
has_many :posts,
:conditions => [‘not_deleted = ?’, true]

Now I’ll give my advice again, hopefully in a working context :slight_smile:

has_many :posts, :conditions => “not_deleted”

No need to compare it to true.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org