I have to implement a message model which would have replies for itself. I ended up something like this:
class Message
include Mongoid::Document
belongs_to :sender, :class_name => "User", :inverse_of => :snt_msg
belongs_to :recipient, :class_name => "User", :inverse_of => :rcvd_msg
embeds_many :replies, :class_name => "Message"
embedded_in :message, :inverse_of => :replies
end
and this for user:
class User
include Mongoid::Document
has_many :snt_msg, :class_name => 'Message', :inverse_of => :sender
has_many :rcvd_msg, :class_name => 'Message', :inverse_of => :recipient
end
Is that Ok to work with it, or is there any well-structure design for that?
Related
class Product < ActiveRecord::Base
belongs_to :parent, :class_name => 'Product', :foreign_key => :parent_id
has_many :children, :class_name => 'Product', :foreign_key => :parent_id
I am trying to add a counter cache to the :children column. I have tried the following:
belongs_to :parent, :class_name => 'Product', :foreign_key => :parent_id
has_many :children, :class_name => 'Product', :foreign_key => :parent_id, counter_cache: true
and also:
has_many :children, :class_name => 'Product', :foreign_key => :parent_id, counter_cache: :children_count
When I run Product.reset_counters(foo.id, :children)
I get the following error:
NoMethodError: undefined method `counter_cache_column' for nil:NilClass
Am I not understanding something fundamental about counter_cache or self-joins? Information about this is scarce and doesn't apply to this type of self-join.
the counter cash should be on the belongs to like
class Child < ActiveRecord::Base
belongs_to :product, counter_cache: true
...
not on the has many in
class Product < ActiveRecord::Base
belongs_to :parent, :class_name => 'Product', :foreign_key => :parent_id
has_many :children, :class_name => 'Product', :foreign_key => :parent_id
but the database column should still be on the product
read through 4.1.2.3 at this link for more info
I have the following relationship. I want a Post to has_one current_wrent but also has_many wrents that keeps tracks of wrent objects. I believe the issue may be related to rails being confused which relationship i'mr eferring to.
When I refer to a post.current_wrent, this is returning correctly with no errors.
Class Post
include Mongoid::Document
include Mongoid::Timestamps
...
has_one :current_wrent, :class_name => "Wrent", :inverse_of => :current_wrent, :autosave => true, :dependent => :destroy
has_many :wrents, :inverse_of => :post, :dependent => :destroy
end
Class Wrent
..
belongs_to :post, :autosave => true
..
end
When I do something like..
(in Wrent.rb)
def accept!
update_attributes!(:status => 1, :accepted => true)
post.current_wrent = self
post.available = false
post.save!
notify_user
end
and I get a "Current Wrent" is invalid error, could somebody point to me something I'm doing wrong here?
EDIT: this seems to work fine.
in wrent.rb
Class Wrent
..
belongs_to :post, :inverse_of => :wrent, :autosave => true
belongs_to :post, :inverse_of => :current_wrent
in post.rb
Class Post
...
has_one :current_wrent, :class_name => "Wrent", :inverse_of => :post
belongs_to :current_wrent, :class_name => "Wrent", :inverse_of => :post
has_many :wrents, :inverse_of => :post, :dependent => :destroy
I'm still not sure what the problem is, but now I can access post.current_wrent through the belongs_to current_wrent_id column and the problem seemed to disappear.
Your Wrent model probably has a post_id field where is stored the id of the Post that it belongs_to. But there's no field in Post to store the current_wrent.
Mongoid allows you to embed objects so what you can do is embeds_one instead has_one.
Class Post
include Mongoid::Document
include Mongoid::Timestamps
...
embeds_one :current_wrent, :class_name => "Wrent", :inverse_of => :current_wrent
has_many :wrents, :inverse_of => :post, :dependent => :destroy
end
I have 2 models: User and PrivateMessage which must be associated (as user has many private messages as reciever and sender, private messages belongs to user)
It's my private_messages table structure:
private_messages:
sender_id:integer
reciever_id:integer
title:string
message:text
It's hard for me to understand how can I connect same message for both sender user and reciever user, now my models code looks like:
class User < ActiveRecord:Base
has_many :private_messages
end
and
class PrivateMessage < ActiveRecord::Base
belongs_to :user, :through => :sender_id
belongs_to :user, :through => :reciever_id
end
Is that correct?
You have to rename your associations to tell them apart:
class PrivateMessage < ActiveRecord::Base
belongs_to :sender, :class_name => 'User', :foreign_key => 'sender_id'
belongs_to :receiver, :class_name => 'User', :foreign_key => 'receiver_id'
end
class User < ActiveRecord::Base
has_many :sent_messages, :class_name => 'PrivateMessage', :foreign_key => 'sender_id', :dependent => :destroy
has_many :received_messages, :class_name => 'PrivateMessage', :foreign_key => 'receiver_id', :dependent => :destroy
end
I am trying to make a private messaging system, where you send a message to one or more users. Now the messages schema is like
user_id, to_id, msg
How do i make the associations so that i can get the details of the sender and the recipient?
schema:
sender_id
recipient_id
class Message
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
class User
has_many :sent_messages, :class_name => 'Message', :foreign_key => :sender_id
has_many :income_messages, :class_name => 'Message', :foreign_key => :recipient_id
end
I have two classes Message and User. Message has sender_id and recipient_id both foreign keys for User. How to build relationship where I'll be able to get user for both sender and recipient, like #message.sender.name and #message.recipient.name
I tried to do it by this way:
class Message < ActiveRecord::Base
belongs_to :sender, :class_name => 'User', :foreign_key => 'sender'
belongs_to :recipient, :class_name => 'User', :foreign_key => 'recipient'
end
class User < ActiveRecord::Base
has_many :recivied_messages, :class_name => 'Message', :foreign_key => 'recipient'
has_many :send_messages, :class_name => 'Message', :foreign_key => 'sender'
end
But it didn't help, when I'm trying to access to, for instance, #message.recipient.name it says that "undefined method `name'"
You can use the :class_name property to set which class gets used for a foreign key:
class Message < ActiveRecord::Base
has_one :sender, :class_name => User
has_one :recipient, :class_name => User
end
class User < ActiveRecord::Base
belongs_to :sent_messages, :class_name => Message
belongs_to :received_messages, :class_name => Message
end
Also, you say you are using sender_id and recipient_id for the foreign keys, but in your code you have :foreign_key => 'sender' and :foreign_key => 'recipient'. Have you tried changing them to :foreign_key => 'sender_id' and :foreign_key => 'recipient_id'? So:
class Message < ActiveRecord::Base
has_one :sender, :class_name => User, :foreign_key => 'sender_id'
has_one :recipient, :class_name => User, :foreign_key => 'recipient_id'
end
class User < ActiveRecord::Base
belongs_to :sent_messages, :class_name => Message, # ...etc
belongs_to :received_messages, :class_name => Message, # ...etc
end