Having a problem getting associations right. In my model I have users and requests. A request has an owner and many participants. A user has many requests and many participations.
I tried to model it like this:
class User
include Mongoid::Document
has_many :requests, inverse_of: :owner
has_many :participations, class_name: 'Request', inverse_of: :participants
...
class Request
include Mongoid::Document
belongs_to :owner, class_name: 'User', inverse_of: :requests
has_many :participants, class_name: 'User', inverse_of: :participations
...
When I try to set a participation by calling
#request.participants << current_user
I get the following error:
message: When adding a(n) User to Request#participants, Mongoid could
not determine the inverse foreign key to set. The attempted key was
'participations_id'. summary: When adding a document to a relation,
Mongoid attempts to link the newly added document to the base of the
relation in memory, as well as set the foreign key to link them on the
database side. In this case Mongoid could not determine what the
inverse foreign key was. resolution: If an inverse is not required,
like a belongs_to or has_and_belongs_to_many, ensure that :inverse_of
=> nil is set on the relation. If the inverse is needed, most likely the inverse cannot be figured out from the names of the relations and
you will need to explicitly tell Mongoid on the relation what the
inverse is. Example: class Lush include Mongoid::Document
has_one :whiskey, class_name: "Drink", inverse_of: :alcoholic end
class Drink include Mongoid::Document belongs_to :alcoholic,
class_name: "Lush", inverse_of: :whiskey end
I don't get it, I have all inverse_of set, what am I doing wrong?
Related
I have 3 relevant tables/models. I would like to retrieve the user which has organized a party, given a Party record, a join table with a boolean organized column, and a users table.
My best attempt so far (this one makes the most sense to me after much fiddling). I've omitted the irrelevant columns.
class Party
# party_id
has_many :parties_users
has_many :users, through: :parties_users, source: :user
has_one :organizer,
-> { where organizer: true },
through: :parties_users,
source: :user
class PartiesUser
# party_id
# user_id
# organized:bool
belongs_to :party
belongs_to :user
class User
# user_id
has_many : parties_users
The above setup raises the following error, which I honestly don't fully understand:
ActiveRecord::HasOneThroughCantAssociateThroughCollection (Cannot have a has_one :through association 'Party#organizer' where the :through association 'Party#parties_users' is a collection. Specify a has_one or belongs_to association in the :through option instead.)
I know I can do this via an instance method, but given the frequency types of use, my app would massively benefit from having this as an association.
As the error message says, you can't have a has_one through a has_many.
You could (instead) do it this way if the organizer flag is on the join record...
has_many :parties_users
has_many :users, through: :parties_users, source: :user
has_one :main_party_user, -> {where organizer: true}, class_name: 'PartiesUser'
has_one :organizer, through: :main_party_user, class_name: 'User'
I have two models User and UserRelation. The case is that User has several related users with himself(recommended by him), but he has only one person related_to(person who recommended him).
I would like to return from User object collection of recommended users and user who recommended him. I have written association for returning users collection and it works but I have no idea how should I write has_one association.
I get this error:
ActiveRecord::HasOneThroughCantAssociateThroughCollection: Cannot have a has_one :through association 'User#relation' where the :through association 'User#user_relations' is a collection. Specify a has_one or belongs_to association in the :through option instead
User model:
class User < ActiveRecord::Base
has_many :user_relations
has_many :related_users, through: :user_relations, source: :related_user
has_one :relation, through: :user_relations, source: :user
end
UserRelation model:
class UserRelation < ActiveRecord::Base
belongs_to :user
belongs_to :related_user, class_name: 'User'
end
UserRelation columns:
user_id
related_user_id
My choice would be to put a foreign key in your User table for the possible related_to field.
If the requirement is that it can only be one (or none) then why not?
You still keep the other "user_relations" for all other types. All the time in rails, we map to the same entity in different ways. It's not uncommon at all
I have two classes
class Round
include Mongoid::Document
include Mongoid::Attributes::Dynamic
has_many :users
end
class User
include Mongoid::Document
include Mongoid::Attributes::Dynamic
belongs_to :round
end
This all works fine, but what I want to have is two methods on the Round model
good_users and bad_users, both is a relation to the User class. I want to reuse the user class, but have a distinct method access.
I understand that the classic model is using a field on user, to associate it with round, so user has a round_id field in the database. but I would be ok with a setup where. the Round class has two fields with the ids of the users as an array, stored in them.
Is this something I can achieve out of the box with mongoid?
This will create two columns in users, for the two relations.
round.rb
has_many :good_users, class_name: 'User', inverse_of: :good_in_round
has_many :bad_users, class_name: 'User', inverse_of: :bad_in_round
user.rb
belongs_to :good_in_round, class_name: 'Round', inverse_of: :good_users
belongs_to :bad_in_round, class_name: 'Round', inverse_of: :bad_users
Mongoid stores the related object ids as an Array in many to many relations. So you could also use that here
round.rb
has_and_belongs_to_many :good_users, class_name: 'User', inverse_of: :good_in_round
has_and_belongs_to_many :bad_users, class_name: 'User', inverse_of: :bad_in_round
I have model relationships like so:
class User
include Mongoid.Document
has_many :favorite_shows
end
class FavoriteShow
include Mongoid.Document
belongs_to :user
belongs_to :show
end
class Show
include Mongoid.Document
has_many :favorite_shows
end
FavoriteShow is a join table between users and shows with both the user_id and show_id as foreign keys. I keep getting the following error despite the fact that these foreign keys already exist:
Problem:
When adding a(n) Show to User#favorite_shows, Mongoid could not determine the inverse foreign key to set. The attempted key was 'user_id'.
Summary:
When adding a document to a relation, Mongoid attempts to link the newly added document to the base of the relation in memory, as well as set the foreign key to link them on the database side. In this case Mongoid could not determine what the inverse foreign key was.
Resolution:
If an inverse is not required, like a belongs_to or has_and_belongs_to_many, ensure that :inverse_of => nil is set on the relation. If the inverse is needed, most likely the inverse cannot be figured out from the names of the relations and you will need to explicitly tell Mongoid on the relation what the inverse is.
Example:
class Lush
include Mongoid::Document
has_one :whiskey, class_name: "Drink", inverse_of: :alcoholic
end
class Drink
include Mongoid::Document
belongs_to :alcoholic, class_name: "Lush", inverse_of: :whiskey
end
Now I've tried adding both inverse_of: nil to the associations, as well as the following with no luck:
class User
include Mongoid.Document
has_many :favorite_shows, class_name: "FavoriteShow", inverse_of: :user
end
class FavoriteShow
include Mongoid.Document
belongs_to :user, class_name: "User", inverse_of: :favorite_shows
belongs_to :show, class_name: "Show", inverse_of: :favorite_shows
end
class Show
include Mongoid.Document
has_many :favorite_shows, class_name: "FavoriteShow", inverse_of: :favorite_shows
end
I have these relationships working perfectly in ActiveRecord, but when switching over to Mongoid, I'm still unclear how the exact relationship is supposed to be translated. Any help would be really appreciated!
When using a document based database such as MongoDB you don't have a need for join tables like you would with a relational database. I suggest a structure like the one below:
class User
include Mongoid::Document
include Mongoid::Timestamps
has_and_belongs_to_many :favorite_shows, class_name: "Show", inverse_of: :users
end
class Show
include Mongoid::Document
include Mongoid::Timestamps
has_and_belongs_to_many :users, class_name: "User", inverse_of: :favorite_shows
end
Can't work out why this is not working
class User
include Mongoid::Document
class Student < User
include Mongoid::Document
....
has_one :parent , class_name: "Parent", inverse_of: :children
class Parent < User
include Mongoid::Document
....
has_many :children, class_name: "Student", inverse_of: :parent
When I try to setup the parent/child relationship via
jane = Student.create!(name: "Jane")
janesParent = Parent.new(name: "Jenny")
janesParent.children.push(jane)
janesParent.save!
I get this error
When adding a(n) Student to Parent#children, Mongoid could not determine the
inverse foreign key to set. The attempted key was 'parent_id'.
What have I done wrong?
P.S I don't want to embed these want to store the id's if applicable types.
If it is 1-N relation, change Student model relation to
belongs_to :parent, class_name: "Parent", inverse_of: :children
Have you tried and has_and_belongs_to_many relation ?