I've got model user and role
class User < ApplicationRecord
rolify strict: true
has_many :roles, through: :users_roles
has_associated_audits
class Role < ApplicationRecord
has_and_belongs_to_many :users, join_table: :users_roles
audited associated_with: :users, join_table: :users_roles
When I create a new role, I've got the error:
2.4.4 :373 > User.first.add_role Role.pi, ProjectRequest.find(319)
User Load (0.7ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
ProjectRequest Load (0.6ms) SELECT `project_requests`.* FROM `project_requests` WHERE `project_requests`.`id` = 319 LIMIT 1
Role Load (0.6ms) SELECT `roles`.* FROM `roles` WHERE `roles`.`name` = 'pi' AND `roles`.`resource_type` = 'ProjectRequest' AND `roles`.`resource_id` = 319 ORDER BY `roles`.`id` ASC LIMIT 1
(0.2ms) BEGIN
SQL (0.6ms) INSERT INTO `roles` (`name`, `resource_type`, `resource_id`, `created_at`, `updated_at`) VALUES ('pi', 'ProjectRequest', 319, '2018-06-19 11:40:13', '2018-06-19 11:40:13')
(54.3ms) ROLLBACK
NoMethodError: undefined method `primary_key' for User::ActiveRecord_Associations_CollectknowProxy:Class
I don't really now whats the problem, did I wrongly specified something?
Look like there is issue with association if it is has_and_belongs_to_many :users and join_table is users_roles on that case in roles table also it should be has_and_belongs_to_many :roles, join_table: :users_roles, and this will make HABM relationship.
I've resolved the problem by this tutorial:
http://blog.flatironschool.com/why-you-dont-need-has-and-belongs-to-many/
What I did was that I removed the HABTM relation and created model for the joining table.
class User < ApplicationRecord
rolify strict: true
has_many :users_roles
has_many :roles, through: :users_roles, dependent: :destroy
has_associated_audits
class Role < ApplicationRecord
has_many :users_roles
has_many :users, through: :users_roles, dependent: :destroy
audited associated_with: :users
class UsersRole < ApplicationRecord
# audited associated_with: :role
audited associated_with: :user
belongs_to :user
belongs_to :role
end
Now when the audits are created with change at the UsersRole instance.
The problem is that, the change's contains only the ids of destroyed columns, so you cannot figure, what it was.
This problem is partially solved there: https://github.com/collectiveidea/audited/issues/72#issuecomment-398756380
Related
I have m:n association with counter cache. I want delete user and remove appropriate records from the users_items association. The sql query which should remove records from users_items association is wrong.
class User < ApplicationRecord
has_many :users_items, class_name: 'UsersItem', dependent: :destroy
has_many :items, through: :users_items
end
class Item < ApplicationRecord
has_many :users_items, class_name: 'UsersItem', dependent: :destroy
has_many :users, through: :users_items
end
class UsersItem < ApplicationRecord
belongs_to :user, counter_cache: true
belongs_to :item, counter_cache: true
end
u = User.last
u.destroy
(0.3ms) BEGIN
UsersItem Load (0.4ms) SELECT "users_items".* FROM "users_items" WHERE "users_items"."user_id" = $1 [["user_id", 41]]
UsersItem Destroy (1.9ms) DELETE FROM "users_items" WHERE "users_items"."" IS NULL
(0.3ms) ROLLBACK
ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR: zero-length delimited identifier at or near """")
LINE 1: DELETE FROM "users_items" WHERE "users_items"."" IS NULL
The problem was with the users_items table. The table was created without primary key. It started working when I added the primary id.
Myth
Users can follow other Users through FollowingRelationship
I would like to be able to say
User.first.followings and it returns a list of Users
This is not working:
Class User
has_many :following_relationships
has_many :followings, through: :following_relationships, foreign_key: :following_id, source: :user
end
Class FollowingRelationship
attr_accessible :following_id, :follower_id
belongs_to :followings, class_name: "User"
end
User.first.followings gives this in console:
SELECT "users".* FROM "users" INNER JOIN "following_relationships" ON "users"."id" = "following_relationships"."user_id" WHERE "following_relationships"."user_id" = 1
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: following_relationships.user_id: SELECT "users".* FROM "users" INNER JOIN "following_relationships" ON "users"."id" = "following_relationships"."user_id" WHERE "following_relationships"."user_id" = 1
Anyone see what piece I am missing?
I think the problem is that FollowingRelationship model doesn't have any relation with User.
It should have belongs_to :user since you specify source: :user, shouldn't it?
I don't quite understand your models and relations between them but belongs_to :followings looks rather strange.
belongs_to uses singular form since it can't belong to more than one object.
UPDATE 1
To be more clear.
I think you should have
class FollowingRelationship
…
belongs_to :user
belongs_to :follower
end
That means followings_relationships table should have user_id and follower_id columns.
UPDATE 2
After some conversation we have figured it out.
Here is the code you should have
class User < ActiveRecord::Base
has_many :fade_relationships, foreign_key: :faded_id
has_many :fadings, through: :fade_relationships, source: :fading
end
class FadeRelationship < ActiveRecord::Base
attr_accessible :faded_id, :fading_id
belongs_to :fading, class_name: "User"
end
I have 2 models with has_one and has_many associations.
realm.rb
class Realm < ActiveRecord::Base
has_one :realm_type, foreign_key: "id"
end
realm_type.rb
class RealmType < ActiveRecord::Base
has_many :realms, foreign_key: "realm_type_id"
end
But when i preforming sql request Realm.find(1).realm_type in rails console, i get
Realm Load (0.3ms) SELECT "realms".* FROM "realms" WHERE "realms"."id" = $1 [["id", 1]]
RealmType Load (0.3ms) SELECT "realm_types".* FROM "realm_types" WHERE "realm_types"."id" = $1 LIMIT 1 [["id", 1]]
As you see, it ignores foreign_key: "realm_type_id" for has_many association in realm_type.rb
UPD 1:
Replaced has_many with belongs_to, still get the same result
Shouldn't you be using belongs_to?
class RealmType < ActiveRecord::Base
has_many :realms, foreign_key: "realm_type_id"
end
class Realm < ActiveRecord::Base
belongs_to :realm_type
end
I just have found a strange behavior of Active Record, where I am not sure if I am the problem or Active Record ;-).
I am using: Rails 4, Ruby 2.0
Here the models:
class User < ActiveRecord::Base
has_many :conversation_participants, dependent: :destroy
has_many :conversations, through: :conversation_participants
end
class ConversationParticipant < ActiveRecord::Base
belongs_to :user
belongs_to :conversation
end
class Conversation < ActiveRecord::Base
has_many :conversation_participants, dependent: :destroy
has_many :participants, through: :conversation_participants, source: :user
end
Pretty straight forward besides the has_many :participants, which refers to user over source:.
Normally, it is possible to call collection_singular_ids on an has_many associated object. Like in this case:
User.find(1).conversation_ids
This works perfectly, I get back an array of conversations ids. But from the other side:
Conversation.find(1).participant_ids
I alway getting back nil. When I go back to the standard for the has_many:
class Conversation < ActiveRecord::Base
has_many :conversation_participants, dependent: :destroy
has_many :users, through: :conversation_participants
end
Conversation.find(1).user_ids
will work fine.
When I look into the resulting queries, I see what the reason could be:
has_many :users creates:
SELECT "users".id FROM "users" INNER JOIN "conversation_participants" ON "users"."id" = "conversation_participants"."user_id" WHERE "conversation_participants"."conversation_id" = $1 [["conversation_id", 29]]
has_many :participants creates:
SELECT "users".* FROM "users" INNER JOIN "conversation_participants" ON "users"."id" = "conversation_participants"."user_id" WHERE "conversation_participants"."conversation_id" = $1 [["conversation_id", 29]]
in the participants case I get a SELECT "users".* instead SELECT "users".id
(using class_name: "User" has also not helped)
Bug or human error?
Ok, check this weirdness out. I have two types of users, leaders and followers (who each have their own subclasses for reasons that please for the love of god I don't want to go into and moreover are not germaine to this discussion).
class Admin < Account
has_many :leader_follower_relationships, foreign_key: :leader_id, dependent: :destroy
has_many :followers, through: :leader_follower_relationships
end
class Follower < Account
has_one :follower_leader_relationship, class_name: "LeaderfollwerRelationship",
dependent: :destroy
has_one :leader, through: :follower_leader_relationship
end
class LeaderFollowerRelationship < ActiveRecord::Base
belongs_to :follower, class_name: "Follower", foreign_key: :artist_id
belongs_to :leader, class_name: "Admin", foreign_key: :leader_id
end
Anyway, I can establish the relationship using a has_one, but I can't update it:
follower1.leader = leader1
(0.3ms) BEGIN
Account Exists (1.1ms) SELECT 1 AS one FROM "accounts" WHERE "accounts"."auth_token" IS NULL LIMIT 1
Account Exists (0.4ms) SELECT 1 AS one FROM "accounts" WHERE "accounts"."email_address" = 'leader1#example.com' LIMIT 1
SQL (0.6ms) ...
(0.5ms) COMMIT
follower1.leader = leader2
(0.3ms) BEGIN
(1.8ms) UPDATE "leader_follower_relationships" SET "leader_id" = 3 WHERE "leader_follower_relationships"."" IS NULL
(0.2ms) ROLLBACK
ActiveRecord::StatementInvalid: PGError: ERROR: zero-length delimited identifier at or near """"
LINE 1: ...ader_id" = 3 WHERE "leader_follower_relationships"."" IS NULL
If my follower can have many leaders (using has_many), I can both create and update:
class Follower < Account
has_many :follower_leader_relationships, class_name: "LeaderfollwerRelationship",
dependent: :destroy
has_many :leaders, through: :follower_leader_relationships
end
These commands work in succession:
follower1.leaders = [leader1]
follower1.leaders = [leader2]
The ActiveRecord error makes me think that the table for your LeaderFollowerRelationship model does not have an id column. If that's not it, can you post the related bits of schema.rb?