Forum: Ruby on Rails Revising named_scope semantics in associated classes

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
1a0fd1d867b858f5f7e1d38dee2918ad?d=identicon&s=25 Sven (Guest)
on 2008-10-22 17:37
(Received via mailing list)
Suppose I have the following models:

  class Post < ActiveRecord::Base
    has_and_belongs_to_many :categories
    named_scope :active, :conditions => {:active => true}
  end

  class Category < ActiveRecord::Base
    has_and_belongs_to_many :posts
  end

I can call Post.active to get the set of all active Post objects. And
I can call some_category.posts.active to get all active Post objects
associated with some_category.

But what if I want slightly different semantics for the active posts
within a category? Perhaps there is an additional condition that
should apply in this case, as suggested by the new method shown here:

  class Category < ActiveRecord::Base
    has_and_belongs_to_many :posts

    def self.active_posts
      channels.active.all :conditions => {:show_in_category => true}
    end
  end

Instead of introducing a new active_posts method, is there any way to
define conditions that should be merged into the named_scope when it
is reference from the associated class?

-Sven
B14575f0ca69f10938fdd67e7156e0e1?d=identicon&s=25 Craig Demyanovich (Guest)
on 2008-10-22 19:16
(Received via mailing list)
I'm a little confused by your example. Do you mean posts instead of
channels? :show_in_category is on Post, correct?

Assuming posts and :show_in_category on Post, couldn't you just add a
second
named_scope to Post, show_in_category (for lack of a better name)?

class Post < ActiveRecord::Base
  named_scope :active, :conditions => { :active => true }
  named_scope :show_in_category, :conditions => { :show_in_category =>
true
}
  ...
end

Then you could do some_category.posts.active or
some_category.posts.active.show_in_category as you see fit.

Thoughts?

Regards,
Craig
1a0fd1d867b858f5f7e1d38dee2918ad?d=identicon&s=25 Sven (Guest)
on 2008-10-22 19:44
(Received via mailing list)
Sorry, I made some mistakes when I tried to simplify my project code.
I'm trying to amend the semantics of an existing named_scope when it's
called from an association, not add an additional one. Here's a more
complete example (which I hope I've gotten right):

  class Post < ActiveRecord::Base
    has_many :category_assignments
    has_many :categories, :through => :category_assignments
    named_scope :active, :conditions => {:active => true}
  end

  class Category < ActiveRecord::Base
    has_many :category_assignments
    has_many :posts, :through => :category_assignments
  end

  class CategoryAssignment < ActiveRecord::Base
    belongs_to :post
    belongs_to :category
    # has attribute show_in_category which allows
    # showing/hiding posts on a per-category basis
  end

I want to be able to do this

  some_category.posts.active

And get the semantics of the active_posts method below:

  class Category < ActiveRecord::Base
    has_many :category_assignments
    has_many :posts, :through => :category_assignment

    def active_posts
      posts.active.all :conditions =>
['category_assignment.show_in_category = ?', true]
    end
  end

So when I call

  Post.active

I get the set of all active posts. But when I call

  some_category.posts.active

I get the set of all active posts in some_category where
show_in_category is true (like calling my active_posts method, but
using a named_scope instead).

One possibility is to do something like this:

  class Category < ActiveRecord::Base
    has_many :category_assignments
    has_many :posts, :through => :category_assignment
    has_many :visible_posts, :class_name => 'Post', :through
=> :category_assignment,
             :conditions => ['category_assignment.show_in_category
= ?', true]
  end

And then remember to call

  some_category.visible_posts.active

This lets me use the named scope instead of a method but the semantics
aren't right. I'm trying to express the notion that active
category.posts are subject to an additional restriction relative to
active posts. I'm not trying to divide _posts_ into two groups. I'm
just trying to restrict _active_ posts within a category.

-Sven
B14575f0ca69f10938fdd67e7156e0e1?d=identicon&s=25 Craig Demyanovich (Guest)
on 2008-10-22 20:12
(Received via mailing list)
On Wed, Oct 22, 2008 at 1:43 PM, Sven <Sven.Aas@gmail.com> wrote:

> ...
> This lets me use the named scope instead of a method but the semantics
> aren't right. I'm trying to express the notion that active
> category.posts are subject to an additional restriction relative to
> active posts. I'm not trying to divide _posts_ into two groups. I'm
> just trying to restrict _active_ posts within a category.


Restricting is dividing your set into those items you want and those you
don't. Since you have attributes across two models, Post#active and
CategoryAssignment#show_in_category, though, I don't think you can
combine
them into one named_scope. I think you'll have to do something like you
suggested at the end of your last message, or you'll have to wrap
everything
in a class method to have the semantics that you want.

Regards,
Craig
This topic is locked and can not be replied to.