SQLite3 error in rails SQLite3::SQLException: no such column - ruby-on-rails

I am making a rails app where a user can post courses and also subscribe to courses.My model files are:
user.rb:
class User < ActiveRecord::Base
has_many :courses, dependent: :destroy
has_many :coursejoins, dependent: :destroy
has_many :learnables, through: :coursejoins, class_name: "Course"
has_many :comments, dependent: :destroy
...
end
course.rb:
class Course < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_many :coursejoins, dependent: :destroy
has_many :students, through: :coursejoins, class_name: "User"
has_many :documents, dependent: :destroy
has_many :comments, dependent: :destroy
...
end
coursejoin.rb:
class Coursejoin < ActiveRecord::Base
belongs_to :learnable, :class_name => "Course"
belongs_to :student, :class_name => "User"
end
20160219171527_create_coursejoins.rb
class CreateCoursejoins < ActiveRecord::Migration
def change
create_table :coursejoins do |t|
t.boolean :accepted
t.timestamps
end
end
end
20160219174937_add_student_id_to_coursejoins.rb
class AddStudentIdToCoursejoins < ActiveRecord::Migration
def change
add_column :coursejoins, :student_id, :integer
end
end
20160219224309_add_learnable_id_to_coursejoins.rb
class AddLearnableIdToCoursejoins < ActiveRecord::Migration
def change
add_column :coursejoins, :learnable_id, :integer
end
end
The coursejoin model is like a relation between a course and a user.
When I try to do #course.students, i get error:
SELECT "users".* FROM "users" INNER JOIN "coursejoins" ON "users"."id" = "coursejoins"."student_id" WHERE "coursejoins"."course_id" = ? [[nil, 1]]
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: coursejoins.course_id: SELECT "users".* FROM "users" INNER JOIN "coursejoins" ON "users"."id" = "coursejoins"."student_id" WHERE "coursejoins"."course_id" = ?
I don't know SQL much so I am not able to decipher the error.
I looked at questions with similar error but none seemed related.
I have been stuck with this for two days.
How do I fix this?

Okay i got this solved and thought i should post the solution for future reference. Basically all that was needed to be done was adding foreign_key: "learnable_id" to "has_many :coursejoins, dependent: :destroy" in course model and foreign_key: "student_id" to has_many :coursejoins, dependent: :destroy to user model.

Related

Has_many through relation "user_roles" does not exist

Hello I try to do a has_many through relation but it's not working as I expect.
Here are my models
def User < ApplicationRecord
has_many :user_roles, class_name: "UserRole"
has_many :roles, through: :user_roles
end
def Role < ApplicationRecord
has_many :user_roles, class_name: "UserRole"
has_many :users, through: :user_roles
end
def UserRole < ApplicationRecord
belongs_to :user
belongs_to :role
end
When I do this in rails console
User.roles
I've got the following error
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: relation "user_roles" does not exist)
I'm stuck with this error since 2 hours and no google result helped me ...
EDIT:
Here is my migration
class CreateUserRole < ActiveRecord::Migration
def change
create_table :user_role do |t|
t.belongs_to :user, type: :uuid
t.belongs_to :role, type: :uuid
end
end
end

RoR: Accessing :through attributes

I'm new to rails and working in this app where an User can create many Events. Many Users can be invited to these Events, therefore I have the following Models:
User:
class User < ActiveRecord::Base
...
has_many :events, dependent: :destroy
end
Event:
class Event < ActiveRecord::Base
belongs_to :user
has_many :event_guest
has_many :guests, :through => :event_guest, :source => :user
end
Event_Guest:
class EventGuest < ActiveRecord::Base
belongs_to :user
belongs_to :event
end
What I am looking for is being able to access (and add) the guest users to an event, for which I've tried all the variations I could thing of "Event.find(1).guests", only to get the following error:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: event_guests.event_id: SELECT "users".* FROM "users" INNER JOIN "event_guests" ON "users"."id" = "event_guests"."user_id" WHERE "event_guests"."event_id" = ? AND "users"."event_id" = 1
My event_guest migration was the following:
create_table :event_guest do |t|
t.belongs_to :user, index: true
t.belongs_to :event, index: true
end
Like #Dharam mentioned, your naming convention is incorrect. You need to rename the event_guest table.
$ rails g migration rename_event_guest_table
And then the migration looks like this:
def change
rename_table :event_guest, :event_guests
end
You then need to update your event.rb model to be
class Event < ActiveRecord::Base
belongs_to :user
has_many :event_guests
has_many :guests, :through => :event_guests, class_name: 'User'
end
And your user.rb model:
class User < ActiveRecord::Base
...
has_many :event_guests, dependent: :destroy
has_many :events, through: :event_guests
end
Move the dependent destroy off the events association and to the event_guests relationship. You don't want to destroy the event just because one guest isn't going...
Try adding self.table_name = "event_guest" to EventGuest as that's what you have in migration which is contrary to rails expectation of "event_guests" from the model name.

Rails One Table Multiple Polymorphic Relations

I have a table (connections) it needs to have multiple Polymorphic Relations. The first one is working but the second gets an error. Here is the layout of the tables. I get this error even if I change has_many :links, as: :linkable to has_many :connection_links, as: :linkable, thinking that it was some reserved word.
class CreateConnections < ActiveRecord::Migration
def change
create_table :connections do |t|
t.integer :connectable_id
t.string :connectable_type
t.integer :linkable_id
t.string :linkable_type
t.boolean :status_id
t.timestamps
end
end
end
class Connection < ActiveRecord::Base
# relations
belongs_to :connectable, polymorphic: true
belongs_to :linkable, polymorphic: true
end
class Person < ActiveRecord::Base
has_many :connections, as: :connectable, dependent: :destroy
has_many :links, as: :linkable, dependent: :destroy
end
class Business < ActiveRecord::Base
has_many :connections, as: :connectable, dependent: :destroy
has_many :links, as: :linkable, dependent: :destroy
end
When I try to pull the links it errors out.
[2] pry(main)> person.connections
Connection Load (0.4ms) SELECT "connections".* FROM "connections" WHERE "connections"."connectable_id" = $1 AND "connections"."connectable_type" = $2 [["connectable_id", 9], ["connectable_type", "Person"]]
=> []
[3] pry(main)> person.links
NameError: uninitialized constant Person::Link
The error is saying that there is no class called Link - doesn't seem like you have one from what you've shown.

Has many :through a Polymorphic association not aliasing type column with Squeel 1.1.1

I've got a few classes:
class Membership < ActiveRecord::Base
belongs_to :group
belongs_to :member, polymorphic: true
end
class User < ActiveRecord::Base
has_many :memberships, as: :member, dependent: :destroy
has_many :groups, through: :memberships
end
class Package < ActiveRecord::Base
has_many :memberships, as: :member, dependent: :destroy
has_many :groups, through: :memberships
end
and
class Group < ActiveRecord::Base
has_many :memberships, dependent: :destroy, inverse_of: :member
has_many :packages, through: :memberships, source: :member, source_type: 'Package'
has_many :users, through: :memberships, source: :member, source_type: 'User'
end
A Users and Packages can have membership in a Group. All of this appears to be ok until I try to get the Users that belong to a Group. In the console, with an instance of a Group g:
[5] pry(main)> g.users
User Load (3.3ms) SELECT "USERS".* FROM "USERS" INNER JOIN "MEMBERSHIPS" ON
"USERS"."ID" = "MEMBERSHIPS"."MEMBER_ID" WHERE "MEMBERSHIPS"."GROUP_ID" = :a1 AND
"USERS"."MEMBER_TYPE" = 'User' [["group_id", 10000]]
OCIError: ORA-00904: "USERS"."MEMBER_TYPE": invalid identifier:
SELECT "USERS".*
FROM "USERS"
INNER JOIN "MEMBERSHIPS" ON "USERS"."ID" = "MEMBERSHIPS"."MEMBER_ID"
WHERE "MEMBERSHIPS"."GROUP_ID" = :a1
AND "USERS"."MEMBER_TYPE" = 'User'
It's easy to see the error - the Users table doesn't have the Member_Type column, it resides on the Membership table.
Why is the column not being aliased appropriately? Anyone else having this problem?
Update
This is an issue with Squeel - removing it from my Gemfile and the association behaves properly.
Logged an issue - https://github.com/ernie/squeel/issues/288

has_many of itself through something

So, I have a system where users are able to follow authors (other users).
User Model:
class User < ActiveRecord::Base
has_many :author_following, class_name: 'Following'
has_many :following, through: :author_following, source: :author
has_many :followers, foreign_key: 'author_id', through: :author_following, source: :user
end
Following Model:
class Following < ActiveRecord::Base
belongs_to :user
belongs_to :author, foreign_key: 'author_id', class_name: "User"
end
Issue: I am able to get the list of authors that i am following, but I am able to get the list of my followers.
Given: u is a valid user that is following others and has followers
u.following generates the following SQL:
SELECT "users".* FROM "users" INNER JOIN "followings" ON "users"."id" = "followings"."author_id" WHERE "followings"."user_id" = $1 [["user_id", 1]]
Which is correct..
u.followers generates the following SQL:
SELECT "users".* FROM "users" INNER JOIN "followings" ON "users"."id" = "followings"."user_id" WHERE "followings"."user_id" = $1 [["user_id", 1]]
Which is wrong..
Ideally this SQL would be WHERE "followings"."author_id" = $1
Of course, I figure it your right after posting the question. However if you think there is a more elegant way of doing this, please comment :)
To solve, I changed:
User Model:
class User < ActiveRecord::Base
has_many :author_following, class_name: 'Following'
has_many :following, through: :author_following, source: :author
has_many :author_followers, foreign_key: 'author_id', class_name: 'Following'
has_many :followers, through: :author_followers, source: :user
end
Following Model:
class Following < ActiveRecord::Base
belongs_to :user
belongs_to :author, class_name: "User"
end
Another way is to use has_and_belongs_to_many. No second model needed.
class User < ActiveRecord::Base
has_and_belongs_to_many :followers, class_name: 'User', foreign_key: 'follower_id'
has_and_belongs_to_many :followees, class_name: 'User', foreign_key: 'followee_id'
end
# Migration
create_table :followees_followers do |t|
t.belongs_to :followee
t.belongs_to :follower
end
This is simpler, but the validation part(say verifying somebody is an author) need to be done in User model
#Billy Chan's answer above is close, but you also need to specify the other side of relationship as well with "association_foreign_key", and switch follower_id with followee_id on our side. Also, join table is users_users actually.
class User < ActiveRecord::Base
has_and_belongs_to_many :followers, class_name: 'User',
foreign_key: 'followee_id', association_foreign_key: 'follower_id'
has_and_belongs_to_many :followees, class_name: 'User',
foreign_key: 'follower_id', association_foreign_key: 'followee_id'
end
# Migration
create_table :users_users do |t|
t.belongs_to :followee
t.belongs_to :follower
end
Now User.followers and User.followees work as expected

Resources