0
votes

Having an issue with has_and_belongs_to_many on my models.

Here's the setup:

  • Ruby - 2.2.0
  • Rails - 4.2.0
  • PostgreSQL - 9.4.4

I have the following models:

class Series < ActiveRecord::Base
   # has_many :series_labels
   # has_many :labels, through: :series_labels
   has_and_belongs_to_many :labels
   has_many :videos
end

class Label < ActiveRecord::Base
  # has_many :series_labels
  # has_many :series, through: :series_labels
  has_and_belongs_to_many :series
end

class LabelSeries < ActiveRecord::Base
  belongs_to :series
  belongs_to :label
end

I have the following migrations:

class CreateSeries < ActiveRecord::Migration
  def change
    create_table :series do |t|

      t.timestamps null: false
    end
  end
end

class AddColumnsToSeries < ActiveRecord::Migration
  def change
    add_column :series, :asset_type, :string
    add_column :series, :duration, :integer
    add_column :series, :external_id, :string
    add_column :series, :asset_created_at, :datetime
    add_column :series, :asset_updated_at, :datetime
    add_column :series, :asset_status, :string
    add_column :series, :asset_hosted_at, :string
    add_column :series, :original_file_name, :string
  end
end

class CreateLabels < ActiveRecord::Migration
  def change
    create_table :labels do |t|
      t.string :value

      t.timestamps null: false
    end
  end
end

class CreateLabelsSeries < ActiveRecord::Migration
  def change
    create_join_table :labels, :series do |t|
      t.index :label_id
      t.index :series_id
    end
  end
end

When I run rails c and supply the following:

s = Series.where(displayName: 'Some Series Name')
s.labels

I get the following error:

NoMethodError: undefined method `labels' for

from /Users/johnhenderson/.rvm/gems/ruby-2.2.0/gems/activerecord-4.2.0/lib/active_record/relation/delegation.rb:136:in

method_missing' from /Users/johnhenderson/.rvm/gems/ruby-2.2.0/gems/activerecord-4.2.0/lib/active_record/relation/delegation.rb:99:in method_missing' from (irb):2 from /Users/johnhenderson/.rvm/gems/ruby-2.2.0/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in start' from /Users/johnhenderson/.rvm/gems/ruby-2.2.0/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in start' from /Users/johnhenderson/.rvm/gems/ruby-2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in console' from /Users/johnhenderson/.rvm/gems/ruby-2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in run_command!' from /Users/johnhenderson/.rvm/gems/ruby-2.2.0/gems/railties-4.2.0/lib/rails/commands.rb:17:in <top (required)>' from bin/rails:4:inrequire' from bin/rails:4:in `'

Best I can tell everything is setup correctly, and there are values in all the tables in the database.

Thanks for any help, John

1

1 Answers

1
votes

The problem here is that Series.where(displayName: 'Some Series Name') returns a collection of Series objects. If you only want a single Series record, use either:

s = Series.where(displayName: 'Some Series Name').first

or

s = Series.find_by(displayName: 'Some Series Name')