do a select from another table within a model

Hey all,

This right here:

  scope :index_blog, {     :select => "blog_posts.*",     :joins => "INNER JOIN categories ON category.id = blog_posts.category_id",     :conditions =>"blog_posts.enabled = 1"   }

returns this:

Mysql2::Error: Not unique table/alias: 'categories': SELECT blog_posts.* FROM `categories` INNER JOIN categories ON category.id = blog_posts.category_id WHERE (blog_posts.enabled = 1)

But I am not trying to select blog_posts.* from categories. I am trying to select blog_posts.* from blog_posts. However, because I do this within the category model, it fills in categories. And I don't know how to select from blog posts from category model. I'm also curious if there is a better way to do this?

Thanks for response.

Unless I misunderstand something can't you just say category.blog_posts with :conditions specified for enabled = 1?

Colin

Hey all,

This right here:

scope :index_blog, { :select => "blog_posts.*", :joins => "INNER JOIN categories ON category.id = blog_posts.category_id", :conditions =>"blog_posts.enabled = 1" }

returns this:

Mysql2::Error: Not unique table/alias: 'categories': SELECT blog_posts.* FROM `categories` INNER JOIN categories ON category.id = blog_posts.category_id WHERE (blog_posts.enabled = 1)

But I am not trying to select blog_posts.* from categories. I am trying to select blog_posts.* from blog_posts. However, because I do this within the category model, it fills in categories. And I don't know how to select from blog posts from category model. I'm also curious if there is a better way to do this?

Why are you trying to define a scope on blog posts in the categories model? Even if you fix the query, rails will still try and create instances of Category rather than instances of BlogPost

Fred

Hey all, This right here:

scope :index_blog, { :select => “blog_posts.*”, :joins => “INNER JOIN categories ON category.id = blog_posts.category_id”, :conditions =>“blog_posts.enabled = 1” }

First of all, “this right here” is in what model/file? I’m gonna guess from your error it is in your Category model in category.rb?

returns this:

Mysql2::Error: Not unique table/alias: ‘categories’: SELECT blog_posts.* FROM categories INNER JOIN categories ON category.id = blog_posts.category_id WHERE (blog_posts.enabled = 1)

Another side problem: “ON category.id…” is your table named categories or category?

But I am not trying to select blog_posts.* from categories. I am trying to select blog_posts.* from blog_posts. However, because I do this within the category model, it fills in categories.

Ahh, so we are in the Category model. This explains why the “FROM categories” part exists. Even though you’re looking for blog_posts, don’t worry about this.

Try:

scope :index_blog, { :select => “blog_posts.*”, :joins => “INNER JOIN blog_posts ON categories.id = blog_posts.category_id”, :conditions =>“blog_posts.enabled = 1” }

I’m also curious if there is a better way to do this?

That depends on what you’re trying to do.

Actually, all i wanted to do initially was this:

def filter_scoper(scoper)     logger.info "The current class is #{self.class}" #CategoriesController

    if params.has_key? :filter       send :"#{params[:filter]}_filter_scoper", scoper     elsif self.class.respond_to?(:blog_filter_scoper)       send :"blog_filter_scoper"     else       scoper #call index_scoper     end   end

Basically if the controller responds to blog_filter_scoper, then I want to pass blog_filter_scoper as the model:

  def blog_filter_scoper     BlogPost   end

However, for some reason despite the fact that self.class outputs CategoriesController and when I load the categories page, it does not respond to the blog_filter_scoper method even though I defined blog_filter_scoper method within the categories controller.

I don't know why this is happening.

ok I must never forget that in haml it works like this:

- @resources.each do |r|   %h1= r.title   %p= r.body

not this:

= @resources.each do |r|   %h1- r.title   %p- r.body

Otherwise, you will get an ActiveRecord array as an object.

Actually, all i wanted to do initially was this: def filter_scoper(scoper) logger.info “The current class is #{self.class}” #CategoriesController

if params.has_key? :filter send :“#{params[:filter]}_filter_scoper”, scoper elsif self.class.respond_to?(:blog_filter_scoper)

Do you mean: elsif self.respond_to?(:blog_filter_scoper) Note the lack of “.class” after self.

send :“blog_filter_scoper” else scoper #call index_scoper end end

Basically if the controller responds to blog_filter_scoper, then I want to pass blog_filter_scoper as the model:

def blog_filter_scoper BlogPost end

Yeah, looks like you’re wanting to call an instance method as I pointed out above.

However, for some reason despite the fact that self.class outputs CategoriesController and when I load the categories page, it does not respond to the blog_filter_scoper method even though I defined blog_filter_scoper method within the categories controller.

I don’t know why this is happening.

It would appear to me that your immediate problem is the line of code I pointed out above.

It would appear to me that your immediate problem is the line of code I pointed out above.

Yeah I got it now. Basically:

if self.class.respond_to?

will only respond to class methods of the class, not instance methods and since attr_accessor returns instance methods, that if will return false. So basically what I had to do was:

    elsif self.class.method_defined? :blog_filter_scoper

And that worked above. And then within my categories controller:

  def blog_filter_scoper     BlogPost.for_posts 1   end

That will call the blogpost named scope and pass the argument 1 so now depending on which controller is invoked, we can pass different arguments to for_posts to determine which posts to display.

The only thing I don't like now about this is that I am passing an integer 1. I'd rather do something like Category[:news].id - where rails will search the categories table with news value and then pull the id of that value which could be 1. I think that's better than hardcoding 1 right there. I guess that's the next thing I need to figure out.

Thanks for all responses.

It would appear to me that your immediate problem is the line of code I pointed out above.

Yeah I got it now. Basically:

if self.class.respond_to?

will only respond to class methods of the class, not instance methods and since attr_accessor returns instance methods, that if will return false. So basically what I had to do was:

It's simpler than that. blah.respond_to?(:foo) returns true if ruby believes you can do blah.foo, so in particular self.class.respond_to?(:blah) checks (in your case) whether CategoriesController.blah can be called whereas self.respond_to?(:blah) checks whether self.blah would work.

method_defined? is a slightly more circuitous route to this and won't always work in a world like rails where methods are often created on the fly from method_missing

Fred