Manoel Ribeiro
Manoel Ribeiro

Reputation: 374

Problems with has_many through Association Rails 4

So i'm trying to do a database that stores the current weather:

 --------------             ------------------            ----------
|              | 1       * |                  |*       1 |          | 
| YearMonthDay |-----------| WeatherCondition |----------| Location |
|              |           |                  |          |          |
 --------------             ------------------            ----------

I generated models using belongs_to and has_many :through

class WeatherCondition < ActiveRecord::Base
    belongs_to :year_month_day
    belongs_to :location
end

class YearMonthDay < ActiveRecord::Base
    has_many :weather_conditions
    has_many :locations, :through => :weather_conditions
 end

class Location < ActiveRecord::Base
    has_many :weather_conditions
    has_many :year_month_days, :through => :weather_conditions
end

And also created a migration for each of them, the YearMonthDay and the Locations ones are just normal and the WeatherConditions is as follows:

class CreateWeatherConditions < ActiveRecord::Migration
  def change
    create_table :weather_conditions do |t|
        t.belongs_to :location, index: true
        t.belongs_to :year_month_day, index: true

      t.timestamps null: false
    end
  end
end

I have no idea what I am doing wrong, but I am getting an error:

 unknown attribute 'year_month_day_id' for WeatherCondition.

Upvotes: 0

Views: 498

Answers (3)

forthowin
forthowin

Reputation: 387

You still have to add the foreign keys to WeatherConditions:

If you are creating a new table:

class CreateWeatherConditions < ActiveRecord::Migration
  def change
    create_table :weather_conditions do |t|
        t.integer :location_id
        t.integer :year_month_day_id

      t.timestamps null: false
    end
  end
end

If you already have the table:

class CreateWeatherConditions < ActiveRecord::Migration
  def change
    add_column :weather_conditions, :location_id, :integer
    add_column :weather_conditions, :year_month_day_id, :integer
  end
end

Upvotes: 2

Matt Stevens
Matt Stevens

Reputation: 1114

Creating a many to many relationship, you need a has_and_belongs_to_many notation.

class YearMonthDay < ActiveRecord::Base
    has_and_belongs_to_many :locations
end

class Location < ActiveRecord::Base
    has_and_belongs_to_many :year_month_days
end

Drop the class for WeatherConditions, you only need the join table which has to be named to match the two models. The names have to be in alphabetical order.

create_table :locations_year_month_days, id: false do |t|
    t.belongs_to :location, index: true
    t.belongs_to :year_month_day, index: true

  t.timestamps null: false
end

Once you have relationship working, you can then call my_date.locations to get an array of location objects tied to that date, or my_location.year_month_dates for vice versa.

This Rails guide has a longer explanation.

Upvotes: 0

virtual_monk
virtual_monk

Reputation: 120

Rails is particular about plural tables. It may not understand how to pluralize year_month_day. What does your schema look like?

Upvotes: 0

Related Questions