I am trying to make a has_many through relationship like this:
#user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :availabilities
has_many :timeslots, :through => availabilities
end
#availability.rb
class Availability < ApplicationRecord
belongs_to :timeslot
belongs_to :user
end
#timeslot.rb
class Timeslot < ApplicationRecord
has_many :availabilities
has_many :timeslots, :through => availabilities
end
I created the two models and than ran rake db:migrate
without adding the code in the models (to create the tables). I made a migration file:
class AddFieldsToTables < ActiveRecord::Migration[5.0]
def change
add_column :users, :availability_id, :integer
add_column :timeslots, :availability_id, :integer
add_column :availabilities, :user_id, :integer
add_column :availabilities, :timeslot_id, :integer
end
end
and ran rake db:migrate
Than I added the code above to all the files. And then if I try to generate anything it gives me NameError: undefined local variable or method availabilities for User (call 'User.connection' to establish a connection):Class
I am new to Ruby on Rails.
I see a tiny problem in your code:
#timeslot.rb
class Timeslot < ApplicationRecord
has_many :availabilities
has_many :timeslots, :through => availabilities
end
it should be:
#timeslot.rb
class Timeslot < ApplicationRecord
has_many :availabilities
has_many :users, :through => availabilities
end
I'm not sure if it can solve your problem but your code (exclude the above mistake) sounds fine for me.
One issue I see is that in your timeslot.rb
you have has_many :timeslots, :through => availabilities
. I'm guessing you want has_many :users, :through => :availabilites
.
Another is in user.rb
, you have has_many :timeslots, :through => availabilities
but you need the symbol :availabilites
. This is what is causing the error you posted, I believe. It should look like this (all I've changed is the second-to-last line):
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :availabilities
has_many :timeslots, :through => :availabilities
end
In order to setup has_many through
relationship between two tables users
and timeslots
, you need to setup join table availabilities
with columns user_id
and timeslot_id
.
Setup your rails models like below:
# models/user.rb
class User < ApplicationRecord
has_many :availabilities
has_many :timeslots, :through => :availabilities
end
# models/availability.rb
# projects table should have these columns - user_id:integer, timeslot_id:integer
class Availability < ApplicationRecord
belongs_to :timeslot
belongs_to :user
end
# models/timeslot.rb
class Timeslot < ApplicationRecord
has_many :availabilities
has_many :users, :through => :availabilities
end
You need a migration to create availabilities
table which acts as a join table for your has_many through relationship between Timeslot
Object and User
Object. Migration file looks something like this:
class CreateAvailabilities < ActiveRecord::Migration[5.0]
def change
create_table :availabilities do |t|
t.integer :user_id
t.integer :timeslot_id
end
end
end
Access
User.last.timeslots
gives 0, 1 or many timeslots associated with User.last
Timeslot.last.users
gives 0, 1 or many users associated with Timeslot.last
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.