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