(PG::UndefinedColumn: ERROR when calling current_user.games - ruby-on-rails

I'm trying to call current_user.games and keep getting the error:
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column assignments.user_id does not exist)
LINE 1: ..." ON "games"."id" = "assignments"."game_id" WHERE "assignmen...
I believe my models are set up right to handle such a query but something tells me I have to run a migration that adds users as a reference?
Models:
class User < ApplicationRecord
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :invitable, invite_for: 2.weeks
has_many :assignments
has_many :games, through: :assignments
end
class Game < ApplicationRecord
has_one :assignment, dependent: :destroy
has_many :users, through: :assignment
after_save :create_assignment
def create_assignment
Assignment.create(game_id: id)
end
end
class Assignment < ApplicationRecord
belongs_to :game
belongs_to :user
# belongs_to :assignor, class_name: "User", optional: true
belongs_to :center_referee, class_name: 'User', optional: true
belongs_to :assistant_referee_1, class_name: 'User', optional: true
belongs_to :assistant_referee_2, class_name: 'User', optional: true
accepts_nested_attributes_for :game
end
Schema:
create_table "assignments", force: :cascade do |t|
t.integer "game_id"
t.integer "center_referee_id"
t.integer "assistant_referee_1_id"
t.integer "assistant_referee_2_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "games", force: :cascade do |t|
t.string "home_team"
t.string "away_team"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "first_name"
t.string "last_name"
t.string "role"
end

Short answer: you won't achieve what you are trying to using has_many. At least not the way your table is designed. You should try using scope instead, unfortunately.
On the other hand, there is a different way to design your system. See the new Assignment. Schema:
create_table "assignments", force: :cascade do |t|
t.integer "game_id"
t.integer "user_id"
end
Models:
class Assignment < ApplicationRecord
belongs_to :game
belongs_to :user
end
class User < ApplicationRecord
has_many :assignments
has_many :games, through: :assignments
end
class Game < ApplicationRecord
has_many :assignments
has_many :users, through: :assignments
end
You may wanna differ a center referee from an assistant referee.
I don't know exactly what your role column at the User model means, so I will assume your role column has nothing to do with center/assistant referee.
If this is the case, I'd add an unsigned tinyint role to Assignment and use it as enum. So my model would be:
class Assignment < ApplicationRecord
belongs_to :game
belongs_to :user
enum role: { center_referee: 0, assistant_referee_1: 1, assistant_referee_2: 2 }
# in case there must be only a kind of referee for a game:
validates(:role, uniqueness: { scope: [:game_id] })
end
And my Schema:
create_table "assignments", force: :cascade do |t|
t.integer "role", limit: 1, unsigned: true
t.integer "game_id"
t.integer "user_id"
end

Related

How do I create groups users can be invited to, invite to and own?

TLDR: Creating groups that users can join with invite features returns a clear error:
PG::UndefinedColumn: ERROR: column user_groups.user_id does not exist
But the answer is not clear to me. UserGroups have an inviter and invitee. Therefore how can I set this up to ensure that the error is not returned?
Problem:
I wish to set up a User, who can join a Group. This relationship will be managed by UserGroup as a user can be a member of multiple groups. A Group will also have a User who is an owner, this is the creator and manager of the group.
A User can also be an Inviter, and may also invite a User who is an Invitee. In order to invite a friend to the group, the User in the case the Inviter will send the Invitee an invite. The Invitee then needs to accept in order to be a member of the Group.
Schema.rb
ActiveRecord::Schema.define(version: 2020_09_29_204316) do
enable_extension "plpgsql"
create_table "addresses", force: :cascade do |t|
t.string "address_type"
t.string "address_line_1"
t.string "address_line_2"
t.string "address_line_3"
t.string "city"
t.string "county"
t.string "postcode"
t.string "country"
t.bigint "user_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["user_id"], name: "index_addresses_on_user_id"
end
create_table "groups", force: :cascade do |t|
t.string "group_name"
t.bigint "owner_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["owner_id"], name: "index_groups_on_owner_id"
end
create_table "offers", force: :cascade do |t|
t.string "partner"
t.string "offer_copy"
t.string "offer_url"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "requests", force: :cascade do |t|
t.bigint "requester_id"
t.bigint "requestee_id"
t.integer "accepted", default: 0
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["requestee_id"], name: "index_requests_on_requestee_id"
t.index ["requester_id"], name: "index_requests_on_requester_id"
end
create_table "user_groups", force: :cascade do |t|
t.bigint "group_id", null: false
t.bigint "invitee_id"
t.bigint "inviter_id"
t.integer "accepted", default: 0
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["group_id"], name: "index_user_groups_on_group_id"
t.index ["invitee_id"], name: "index_user_groups_on_invitee_id"
t.index ["inviter_id"], name: "index_user_groups_on_inviter_id"
end
create_table "users", force: :cascade do |t|
t.string "first_name", default: "", null: false
t.string "last_name", default: "", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.date "birthday", default: "2020-10-22", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "invitation_token"
t.datetime "invitation_created_at"
t.datetime "invitation_sent_at"
t.datetime "invitation_accepted_at"
t.integer "invitation_limit"
t.string "invited_by_type"
t.bigint "invited_by_id"
t.integer "invitations_count", default: 0
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["invitation_token"], name: "index_users_on_invitation_token", unique: true
t.index ["invitations_count"], name: "index_users_on_invitations_count"
t.index ["invited_by_id"], name: "index_users_on_invited_by_id"
t.index ["invited_by_type", "invited_by_id"], name: "index_users_on_invited_by_type_and_invited_by_id"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
add_foreign_key "addresses", "users"
add_foreign_key "groups", "users", column: "owner_id"
add_foreign_key "requests", "users", column: "requestee_id"
add_foreign_key "requests", "users", column: "requester_id"
add_foreign_key "user_groups", "groups"
add_foreign_key "user_groups", "users", column: "invitee_id"
add_foreign_key "user_groups", "users", column: "inviter_id"
end
Groups Migration
class CreateGroups < ActiveRecord::Migration[6.0]
def change
create_table :groups do |t|
t.string :group_name
t.references :owner, foreign_key: { to_table: :users }
t.timestamps
end
end
end
UserGroups Migration
class CreateUserGroups < ActiveRecord::Migration[6.0]
def change
create_table :user_groups do |t|
t.references :group, null: false, foreign_key: true, null: false
t.references :invitee, foreign_key: { to_table: :users }
t.references :inviter, foreign_key: { to_table: :users }
t.integer :accepted, default: 0
t.timestamps
end
end
end
User.rb (Model)
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :trackable
validates :first_name, :last_name, :birthday, presence: true
has_many :accepted_sent_requests, -> { where accepted: 1 }, foreign_key: :requester_id, class_name: 'Request'
has_many :friends, through: :accepted_sent_requests, source: :requestee
has_many :sent_requests, foreign_key: :requester_id, class_name: 'Request', dependent: :destroy
has_many :received_requests, foreign_key: :requestee_id, class_name: 'Request', dependent: :destroy
has_many :requestees, through: :sent_requests, dependent: :destroy
has_many :requesters, through: :received_requests, dependent: :destroy
has_many :user_groups
has_many :accepted_sent_invites, -> { where accepted: 1 }, foreign_key: :inviter_id, class_name: 'UserGroup'
has_many :friend_groups, through: :accepted_sent_invites, source: :invitee
has_many :sent_invites, foreign_key: :inviter_id, class_name: 'UserGroup', dependent: :destroy
has_many :received_invites, foreign_key: :invitee_id, class_name: 'UserGroup', dependent: :destroy
has_many :invitees, through: :sent_invites, dependent: :destroy
has_many :inviters, through: :received_invites, dependent: :destroy
has_many :groups, through: :user_groups
has_many :groups_owned, foreign_key: :owner_id, class_name: 'Group'
has_many :addresses, dependent: :destroy
searchkick match: :word, searchable: [:email]
after_create :send_welcome_email
private
def send_welcome_email
unless invitation_token?
UserMailer.with(user: self).welcome.deliver_now
end
end
def search_data
{
email: email
}
end
end
UserGroup.rb (Model)
class UserGroup < ApplicationRecord
belongs_to :inviter, class_name: 'User', optional: true
belongs_to :invitee, class_name: 'User', optional: true
belongs_to :group, optional: true
def accept
self.update_attributes(accepted: 1)
Request.create!(inviter_id: self.invitee_id,
invitee_id: self.inviter_id,
accepted: 1)
end
end
Group.rb (Model)
class Group < ApplicationRecord
has_many :user_groups
has_many :users, through: :user_groups
belongs_to :owner, class_name: 'User'
end
The above error was solved by editing the User model to include the association for the user_groups:
has_many :user_groups, foreign_key: :inviter_id, class_name: 'UserGroup'
has_many :user_groups, foreign_key: :invitee_id, class_name: 'UserGroup'
has_many :groups, through: :user_groups, foreign_key: :inviter_id, class_name: 'UserGroup'
has_many :groups, through: :user_groups, foreign_key: :invitee_id, class_name: 'UserGroup'
To quote #james00794:
The error is quite clear. It is saying that there is no user_id column
on the user_groups table, which is true according to your schema. Your
has_many :groups, through: :user_groups is likely what is causing the
error when you call user.groups, since the has_many :user_groups
relation does not specify a foreign key. Rails then implicitly assumes
that the column is called user_id. If you specify a foreign_key on the
has_many :user_groups relation, this should resolve your error. Though
you may need separate through relations for the inviters and invitees.

Dilemma between two database schemas for my marketplace rails project

I'm building a market place when a User can both buy and sell.
Of course he will not be able to buy his own products and once one of his product will be buyed there will be a quantity logic controller behind. However. I'm still stuck at modeling the schema.
At the moment i'm using this schema.
ActiveRecord::Schema.define(version: 2018_09_11_202223) do
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "orders", force: :cascade do |t|
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_orders_on_user_id"
end
create_table "orders_products", id: false, force: :cascade do |t|
t.integer "order_id", null: false
t.integer "product_id", null: false
t.index ["order_id", "product_id"], name: "index_orders_products_on_order_id_and_product_id"
t.index ["product_id", "order_id"], name: "index_orders_products_on_product_id_and_order_id"
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "tagline"
t.integer "user_id"
t.integer "category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "price"
t.text "description"
t.index ["category_id"], name: "index_products_on_category_id"
t.index ["user_id"], name: "index_products_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
Whit these models:
class Category < ApplicationRecord
has_many :products
end
class Order < ApplicationRecord
has_and_belongs_to_many :products
belongs_to :user
end
class Product < ApplicationRecord
has_and_belongs_to_many :orders
belongs_to :category
belongs_to :user
end
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :orders, :dependent => :destroy
has_many :products, :dependent => :destroy
end
So basically i'm about to use a HABTOM (has_and_belongs_to_many) associations between the table Orders and Products as you can see inside my models, because an order can have many products and a product can be in many orders( here i'm not sure xD, i think i'm wrong ). Anyway, my dilemma is this, since i've read on internet that in the most of the cases, in situations like this you can use the has_many :through association (HMTA), something like this:
class Category < ApplicationRecord
has_many :products
end
class User
has_many :orders
has_many :products, through: :orders
end
class Order
belongs_to :user
belongs_to :product
end
class Product
belongs_to :category
has_many :orders
has_many :users, through: :orders
end
keep in mind that in my marketplace i want the people can both buy and sell, that's why a User can have many products but the product must be unique and should belong to only one specific User, for instance an old car, doesn't exist two cars exactly identical, that's why i used this association in my Product model:
class Product < ApplicationRecord
has_and_belongs_to_many :orders
belongs_to :category
belongs_to :user
end
so in the end what do you suggest me to do? should i switch from the HABTOM association to a HMTA? In this case, let's say i want to sell a product, how can i manage the User and Product association? is it possible just using a has_many :through association? Thank you
the product must be unique and should belong to only one specific User
The point is that there needs to be two links between the products table and the users table.
You need the concept of a "seller" as well as "buyers" (or whatever you choose to name it).
Something like this:
class Product < ApplicationRecord
belongs_to :seller, class_name: "User"
has_many :buyers, through: :orders, class_name: "User"
end
class User
has_many :orders
has_many :products_bought, through: :orders, class_name: 'Product'
has_many :products_sold, class_name: 'Product'
end
You can then add a uniqueness validation check on the product (possibly scoped to the seller_id?).
If one product had multiple sellers, then you could tweak this association slightly to use a more generic join table (i.e. rename the orders table). But you still need a clear distinction between the "sellers" and the "buyers".

Rails single through table for multiple models

Whenever i try to add any of the user's role (say admin) and grade in user_grade table it is giving errors other roles must exist (teacher, student, guardian). I don't know how to fix this as this is bit complex relationship structure.
or can anyone suggest any better way of doing this?
class Admin < User
# can post many posts
has_many :posts, dependent: :destroy , foreign_key: 'user_id'
# admin post can have many tags
has_many :post_tags, dependent: :destroy, foreign_key: 'user_id'
has_many :tags , through: :post_tags
# can have many grades to see other grades posts
has_many :user_grades, foreign_key: 'user_id'
has_many :grades, through: :user_grades
end
class Teacher < User
# can post many posts
has_many :posts, dependent: :destroy , foreign_key: 'user_id'
# teacher post can have many tags
has_many :post_tags, dependent: :destroy, foreign_key: 'user_id'
has_many :tags , through: :post_tags
# can teach many grades
has_many :user_grades, dependent: :destroy, foreign_key: 'user_id'
has_many :grades , through: :user_grades
end
class Student < User
# a student can only in particular grade
has_one :user_grade , dependent: :destroy, foreign_key: 'user_id'
has_one :grade , through: :user_grade
end
class Guardian < User
# parents can have many children in different classes
has_many :user_grades, dependent: :destroy, foreign_key: 'user_id'
has_many :grades, through: :user_grades
end
class Grade < ApplicationRecord
has_many :user_grades, dependent: :destroy
has_many :admins, through: :user_grades
has_many :teachers, through: :user_grades
has_many :students , through: :user_grades
has_one :guardian, through: :user_grade
end
class UserGrade < ApplicationRecord
belongs_to :grade
belongs_to :admin
belongs_to :teacher
belongs_to :student
belongs_to :guardian
end
Database:
ActiveRecord::Schema.define(version: 20180410102940) do
create_table "grades", force: :cascade do |t|
t.integer "cls"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "post_tags", force: :cascade do |t|
t.integer "user_id"
t.integer "post_id"
t.integer "tag_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", force: :cascade do |t|
t.integer "user_id", null: false
t.string "title"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "roles", force: :cascade do |t|
t.string "name"
t.string "resource_type"
t.integer "resource_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
t.index ["name"], name: "index_roles_on_name"
t.index ["resource_type", "resource_id"], name: "index_roles_on_resource_type_and_resource_id"
end
create_table "tags", force: :cascade do |t|
t.string "tag_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "user_grades", force: :cascade do |t|
t.integer "user_id"
t.integer "grade_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.integer "failed_attempts", default: 0, null: false
t.string "unlock_token"
t.datetime "locked_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "type"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["unlock_token"], name: "index_users_on_unlock_token", unique: true
end
create_table "users_roles", id: false, force: :cascade do |t|
t.integer "user_id"
t.integer "role_id"
t.index ["role_id"], name: "index_users_roles_on_role_id"
t.index ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id"
t.index ["user_id"], name: "index_users_roles_on_user_id"
end
end
I used rolify and cancancan gem here for user's role.
Try adding optional parameter to belongs_to relation
class UserGrade < ApplicationRecord
belongs_to :grade
belongs_to :admin, optional: true
belongs_to :teacher, optional: true
belongs_to :student, optional: true
belongs_to :guardian, optional: true
end
Rails 5 makes belongs_to association required by default. We can avoid validation on belongs_to relation by adding optional: true.
OR
You can turn off this behaviour for all models by keeping the value of belongs_to_required_by_default to false.
# file => config/application.rb
config.active_record.belongs_to_required_by_default = false

Rails 4, specify custom foreign key in has_many through join table?

I would like to specify a custom foreign key in the join table for a has_many through association in my rails 4 app. Please see below, what I have so far...
When I execute user.team_memberships.create in the rails console, I receive this error:
ActiveRecord::UnknownAttributeError: unknown attribute 'user_id' for TeamMembership.
users.rb
class User < ActiveRecord::Base
has_many :team_memberships
has_many :teams, through: :team_memberships
teams.rb
class Team < ActiveRecord::Base
has_many :team_memberships
has_many :members, through: :team_memberships
team_membership.rb
class TeamMembership < ActiveRecord::Base
belongs_to :member, class_name: 'User', foreign_key: 'member_id'
belongs_to :team
schema.rb
create_table "team_memberships", force: :cascade do |t|
t.integer "member_id"
t.integer "team_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "team_memberships", ["member_id"], name: "index_team_memberships_on_member_id", using: :btree
add_index "team_memberships", ["team_id"], name: "index_team_memberships_on_team_id", using: :btree
create_table "teams", force: :cascade do |t|
t.string "name"
t.integer "team_snap_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.integer "teamsnap_uid"
t.string "teamsnap_access_token"
end
You'll need to add foreign_key: 'member_id' to the has_many declaration on User. You can also remove the foreign_key option on the belongs_to in TeamMembership - Rails will infer this automatically.
user.rb
class User < ActiveRecord::Base
has_many :team_memberships, foreign_key: 'member_id'
has_many :teams, through: :team_memberships
team_membership.rb
class TeamMembership < ActiveRecord::Base
belongs_to :member, class_name: 'User'
belongs_to :team
You need to specify foreign key in both models
class User < ActiveRecord::Base
has_many :team_memberships, foreign_key: 'member_id'
has_many :teams, through: :team_memberships
end
and
class TeamMembership < ActiveRecord::Base
belongs_to :member, class_name: 'User', foreign_key: 'member_id'
belongs_to :team
end
if you do not add foreign key in user model then you will not be able to create team membership for a user similarly if you will not specify foreign key in team membership then you will not able to get user of a team membership.

Has many associations error when not using default column name

I cannot make good associations when the foreign key has not the default name.
I would like to access to all subjects which belongs_to one participant (foreign key = questioner_id).
It raise me an error
p = Participant.first
p.subjects
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: subject_participants.participant_id: SELECT "participants".* FROM "participants" INNER JOIN "subject_participants" ON "participants"."id" = "subject_participants"."subject_id" WHERE "subject_participants"."participant_id" = ?
Why does it looks for subject_participants.participant_id ? It's just a has_many association, I don't think that subject_participants table should be called in this case...
interested_id and questioner_id are from the same model but not the same role. One has to go through subject_participants table and the other has to go directly in subjects table
My models :
participant.rb
class Participant < ActiveRecord::Base
has_many :subjects, foreign_key: "questioner_id", class_name: "Participant" #questioner
has_many :subjects, through: :subject_participants, foreign_key: "interested", class_name: "Participant" #interested
has_many :subject_participants
has_many :conference_participants
has_many :conferences, through: :conference_participants
end
subject.rb
class Subject < ActiveRecord::Base
validates_presence_of :title, :questioner, :conference, :description
has_many :subject_participants
has_many :interested, through: :subject_participants, :class_name => "Participant" #interested
belongs_to :questioner, :class_name => "Participant"
belongs_to :conference
end
subject_participant.rb
class SubjectParticipant < ActiveRecord::Base
validates_presence_of :interested_id, :subject_id
belongs_to :interested, :class_name => "Participant"
belongs_to :subject
end
schema.rb
create_table "participants", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
end
add_index "participants", ["email"], name: "index_participants_on_email", unique: true
add_index "participants", ["reset_password_token"], name: "index_participants_on_reset_password_token", unique: true
create_table "subject_participants", force: :cascade do |t|
t.integer "interested_id"
t.integer "subject_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "subjects", force: :cascade do |t|
t.string "title", null: false
t.text "description"
t.integer "questioner_id", null: false
t.integer "conference_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Change your participant.rb to
class Participant < ActiveRecord::Base
.....
has_many :subject_participants,class_name: "SubjectParticipant", foreign_key: "interested_id"
end
You make me find the solution, thanks for help :
participant.rb
class Participant < ActiveRecord::Base
has_many :subject_participants, class_name: "SubjectParticipant", foreign_key: "interested_id"
has_many :subjects_interested_in, through: :subject_participants, :source => "subject"
has_many :subjects, foreign_key: "questioner_id"
has_many :conference_participants
has_many :conferences, through: :conference_participants
end
subject.rb
class Subject < ActiveRecord::Base
validates_presence_of :title, :questioner, :conference, :description
has_many :subject_participants
has_many :interested, through: :subject_participants #interested
belongs_to :questioner, class_name: "Participant"
belongs_to :conference
end

Resources