Guanlun
Guanlun

Reputation: 1608

Rails - column not found for defined 'has_many' relationship

I define a Post class which can link or be linked to multiple posts. To do this I added a PostLink class which specifies post_to and post_from.

I generated the PostLink class by rails g model post_link from_post:integer to_post:integer and of course rake db:migrate, and added

belongs_to :from_post, :class_name => 'Post' 
belongs_to :to_post, :class_name => 'Post'

to the class.

And I also have has_many :post_links in my Post class.

I ran rails console and Post.new.post_links and got nil printed out, which is expected. However after I save a Post using

p = Post.new
p.save

and then run p.post_links, it prints out the following error message:

SQLite3::SQLException: no such column: post_links.post_id: SELECT "post_links".* 
FROM "post_links"  WHERE "post_links"."post_id" = 1

So anybody know why after saving it to the database post_link can not be accessed?

Upvotes: 0

Views: 173

Answers (1)

rossta
rossta

Reputation: 11494

The has_many :post_links association in Post throws an error because it assumes the foreign key in post_links is post_id by default. Since you are using from_post_id and to_post_id, you will have to find a way to group the post_links for "from" posts and "to" posts to get the total set of post_links for a post.

One approach could be to define two associations on Post and an additional method to add the sets together:

class Post < ActiveRecord::Base

  has_many :from_post_links, :class_name => 'PostLink', :foreign_key => :from_post_id
  has_many :to_post_links, :class_name => 'PostLink', :foreign_key => :to_post_id'

  def post_links
    from_post_links + to_post_links
  end

end

As another option, you could provide special sql to the association to group the sets in a single query:

class Post < ActiveRecord::Base

  has_many :post_links, :finder_sql => Proc.new {
    %Q{
      SELECT *
      FROM post_links pl
      WHERE pl.to_post_id = #{id} 
      OR pl.from_post_id = #{id}
    }
  }

Upvotes: 1

Related Questions