Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails has_many :through PG::Error: ERROR: column reference "id" is ambiguous error

I'm new to rails and I've been trying to get two has_many :though relationships to work out (as opposed to using has_and_belongs_to_many as explained by this post http://blog.flatironschool.com/post/35346328762/why-you-dont-need-has-and-belongs-to-many) but am now running into a Postgres error:

PG::Error: ERROR:  column reference "id" is ambiguous
LINE 1: ...on_id" IS NULL AND "components"."id" = 1 ORDER BY id ASC LIM...
                                                             ^
: SELECT  1 AS one FROM "components" INNER JOIN "collection_components" ON "components"."id" = "collection_components"."component_id" WHERE "collection_components"."collection_id" IS NULL AND "components"."id" = 1 ORDER BY id ASC LIMIT 1
  Rendered collections/_form.html.haml (117.0ms)
  Rendered collections/new.html.haml within layouts/application (143.5ms)
Completed 500 Internal Server Error in 164ms

ActiveRecord::StatementInvalid - PG::Error: ERROR:  column reference "id" is ambiguous
LINE 1: ...on_id" IS NULL AND "components"."id" = 1 ORDER BY id ASC LIM...
                                                             ^

_form.html.haml

= form_for @collection do |f|
  - if @collection.errors.any?
    #error_explanation
      %h1= "#{pluralize(@collection.errors.count, "error")} prohibited this collection from being saved:"
      %ul
        - @collection.errors.full_messages.each do |msg|
          %li= msg

  .field
    - Component.all.each do |component|
      = label_tag :component_ids, component.id
      = check_box_tag :component_ids, component.id, @collection.components.include?(component), :name => 'collection[component_ids][]'
  .field
    = f.label :title
    = f.text_field :title
  .actions
    = f.submit 'Save'

collection_component.rb

class CollectionComponent < ActiveRecord::Base
  attr_accessible :collection_id, 
                  :component_id

  belongs_to      :collection
  belongs_to      :component
end

collection.rb

class Collection < ActiveRecord::Base
  default_scope order('id ASC')

  attr_accessible         :style_id, 
                          :name, 
                          :title,
                          :component

  #has_and_belongs_to_many :components

  has_many                :collection_components, :dependent => :destroy
  has_many                :components, :through => :collection_components

  belongs_to              :style

  validates_presence_of   :style
  validates_presence_of   :title

  before_save             :create_name

  private

  def create_name
    self.name = title.parameterize
  end
end

component.rb

class Component < ActiveRecord::Base
  default_scope order('id ASC')

  attr_accessible         :category_id, 
                          :name, 
                          :title,
                          :collection,
                          :style

  has_many                :collection_components, :dependent => :destroy
  has_many                :collections,   :through => :collection_components

  has_many                :component_styles
  has_many                :styles,        :through => :component_styles

  belongs_to              :category

  validates_presence_of   :category
  validates_presence_of   :title

  before_save             :create_name

  private

  def create_name
    self.name = title.parameterize
  end
end

collection_components table

Column     |            Type             |                             Modifiers                              
---------------+-----------------------------+--------------------------------------------------------------------
 id            | integer                     | not null default nextval('collection_components_id_seq'::regclass)
 collection_id | integer                     | 
 component_id  | integer                     | 
 created_at    | timestamp without time zone | not null
 updated_at    | timestamp without time zone | not null
Indexes:
    "collection_components_pkey" PRIMARY KEY, btree (id)  

collections table

Column   |            Type             |                        Modifiers                         
------------+-----------------------------+----------------------------------------------------------
 id         | integer                     | not null default nextval('collections_id_seq'::regclass)
 style_id   | integer                     | 
 name       | character varying(255)      | 
 title      | character varying(255)      | 
 created_at | timestamp without time zone | not null
 updated_at | timestamp without time zone | not null
Indexes:
    "collections_pkey" PRIMARY KEY, btree (id)

components table

   Column    |            Type             |                        Modifiers                        
-------------+-----------------------------+---------------------------------------------------------
 id          | integer                     | not null default nextval('components_id_seq'::regclass)
 name        | character varying(255)      | 
 title       | character varying(255)      | 
 category_id | integer                     | 
 created_at  | timestamp without time zone | not null
 updated_at  | timestamp without time zone | not null
Indexes:
    "components_pkey" PRIMARY KEY, btree (id)
like image 852
Eric Norcross Avatar asked Apr 08 '13 17:04

Eric Norcross


1 Answers

Try this:

  default_scope { order('collections.id ASC') } //collection.rb
  default_scope { order('components.id ASC') } //component.rb

When you perform a join ascending on id becomes ambiguous column because both components and collections have id column. It will not know which to use.

like image 59
Rahul Tapali Avatar answered Sep 21 '22 12:09

Rahul Tapali