Allow to use Proc on :order option of associations

349 views
Skip to first unread message

Gabriel Sobrinho

unread,
May 3, 2012, 2:28:14 PM5/3/12
to rubyonra...@googlegroups.com
Take a look (not my production code but reproduces the desired behavior):

``` ruby
class Post < ActiveRecord::Base
  attr_accessible :published_at, :name

  has_and_belongs_to_many :categories, :order => lambda { [Category.arel_table[:published_at].desc, Category.arel_table[:name]] }
end
```

``` ruby
class Category < ActiveRecord::Base
  attr_accessible :published_at, :name

  has_and_belongs_to_many :posts, :order => lambda { [Post.arel_table[:published_at].desc, Post.arel_table[:name]] }
end
```

``` ruby
Category.first.posts
# => TypeError: Cannot visit Proc
```

``` ruby
Post.first.categories
# => TypeError: Cannot visit Proc
```

The problem happens when we have a cross reference between two models and need to use arel due to difference on quote of columns.

Sounds reasonable?

Jon Leighton

unread,
May 4, 2012, 6:48:34 AM5/4/12
to rubyonra...@googlegroups.com
There has been discussion about putting a new syntax into Rails 4 that
more closely resembles scopes. Example:

has_many :comments, -> { where(deleted: false).order(:created_at) }

This would solve the problem of eager evaluation because it's contained
in a lambda.

I'll be looking into this when I get around to it.
> --
> You received this message because you are subscribed to the Google
> Groups "Ruby on Rails: Core" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/rubyonrails-core/-/I5NDxR9PCvgJ.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to
> rubyonrails-co...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/rubyonrails-core?hl=en.

--
http://jonathanleighton.com/

Gabriel Sobrinho

unread,
May 4, 2012, 8:55:32 AM5/4/12
to rubyonra...@googlegroups.com
Thanks John!
> To post to this group, send email to rubyonrails-core@googlegroups.com.
> To unsubscribe from this group, send email to
> rubyonrails-core+unsubscribe@googlegroups.com.

Rodrigo Rosenfeld Rosas

unread,
May 4, 2012, 9:54:08 AM5/4/12
to rubyonra...@googlegroups.com
Em 04-05-2012 07:48, Jon Leighton escreveu:
There has been discussion about putting a new syntax into Rails 4 that more closely resembles scopes. Example:

has_many :comments, -> { where(deleted: false).order(:created_at) }

For this particular case, I don't understand. What would be the advantage of lazy evaluation?

Take a look at how some examples are handled in Sequel with regards to associations:

http://sequel.rubyforge.org/rdoc/files/doc/association_basics_rdoc.html

See section Association Options

So, for that particular case, a single block would be enough without the need for a proc. Here is an example using Sequel:

many_to_one(:comments){|ds| ds.where(deleted: false).order(:created_at) }

Procs would be useful for some cases where you depend on some dynamic data (taken from the Sequel documentation with a small typo fix):

Artist.one_to_many :songs, dataset: -> {
  Song.select(:songs.*).join(Lyric, id: :lyric_id,
    id => [:composer_id, :arranger_id, :vocalist_id, :lyricist_id])
}
Artist.first.songs_dataset
# SELECT songs.* FROM songs
# INNER JOIN lyrics ON
#  lyrics.id = songs.lyric_id AND
#  1 IN (composer_id, arranger_id, vocalist_id, lyricist_id)

Also, I much prefer such approach as a generalized one than the AR 'finder_sql' option in a sense that it could be more easily cascaded with other conditions.

Am I missing something?

Cheers,
Rodrigo.

Gabriel Sobrinho

unread,
May 4, 2012, 10:14:21 AM5/4/12
to rubyonra...@googlegroups.com
Yep, cross-reference.

Both file needs to require the other to load :)


Category definition needs Post defined
Post definition needs Category defined


We simply can't load these files in this way.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.

Cheers,

Gabriel Sobrinho

Rodrigo Rosenfeld Rosas

unread,
May 4, 2012, 10:32:18 AM5/4/12
to rubyonra...@googlegroups.com
Ah, I see, thanks.
Reply all
Reply to author
Forward
0 new messages