How to query unique documents for a given field where there is a referenced 1-N relationship in Mongoid? - ruby

class User
include Mongoid::Document
has_many :foos
end
class Foo
include Mongoid::Document
include Mongoid::Timestamps
field :group_id, type:String
belongs_to :user
end
Each Foo belongs to a group with a group_id. However, there is no Group model.
What is an efficient way to get the single latest (highest created_at) Foo for each group_id?

Related

How do I create two relations in one document

I am using mongomapper and I am saving association using the following method:
class Task
include MongoMapper::Document
key :user_id, ObjectId #also works without this line
belongs_to :user
def self.add(user)
a = self.new
a.user_id = user
a.save
end
And in the User model I have added: many :Tasks
Now, I would like to save two users (in the html form I select 2 users from the Users collection), without using the array, I want to save them separately:
class Task
include MongoMapper::Document
key :from_user_id, ObjectId # user1 links to the Users model
key :to_user_id, ObjectId # user2 links to the Users model
How od I do that?
MongoMapper has similar options as ActiveRecord when it comes to specifying keys and class names. You'd do something like:
class Task
include MongoMapper::Document
key :to_user_id, ObjectId
key :from_user_id, ObjectId
belongs_to :from_user, class_name: 'User', foreign_key: :from_user_id
belongs_to :to_user, class_name: 'User', foreign_key: :to_user_id
end

has_and_belongs_to_many model creation needed?

I have orders and items table. I also have a third table called orders_items. Which I learned on creating from the following link (2nd graph) http://www.tutorialspoint.com/ruby-on-rails/rails-models.htm
models/order.rb
class Order < ActiveRecord::Base
has_and_belongs_to_many :items, through: :item_order
end
models/item.rb
class Item < ActiveRecord::Base
has_and_belongs_to_many :orders, through: :item_order
end
[orders_items] table has the following:
integer :order_id
integer :item_id
Do I have to create a models/order_item.rb file to add:
belongs_to :order
belongs_to :item
If so what is the correct naming format that it should be?
Would the name for the model file [order_item.rb] correct to distinguish which table it refers to?
models/order_item.rb ??
class OrdersItem ??? < ActiveRecord::Base
belongs_to :order
belongs_to :item
end
From the API
The join table should not have a primary key or a model associated
with it. You must manually generate the join table with a migration
such as this
class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
def change
create_table :developers_projects, id: false do |t|
t.integer :developer_id
t.integer :project_id
end
end
end
Specifies a many-to-many relationship with another class. This
associates two classes via an intermediate join table. Unless the join
table is explicitly specified as an option, it is guessed using the
lexical order of the class names. So a join between Developer and
Project will give the default join table name of “developers_projects”
because “D” precedes “P” alphabetically
In your case the join table name should be items_orders.
Your model must be named OrderItem. And you don't need belongs_to in this class. The file name (order_item.rb) is correct.
I think you need this relationship to fulfill your needs, except if orders is an item too
class Order < ActiveRecord::Base
has_many :items
end
and
class Item < ActiveRecord::Base
belongs_to :order
end

Configure Mongoid relation to return objects sorted

I have two classes with a 1-n relationship. Like so:
class Band
include Mongoid::Document
has_many :members
end
class Member
include Mongoid::Document
field :name, type: String
field :joined, type: Date
belongs_to :band
end
Now when I call band.members I get the member objects. What I want is that if I call band.members.last to get the member who joined the last. I achieve this by defining the <=> method for Member and sort based on joined:
band.members.sort.last
How can I make this behavior default? I don't want to avoid the extra call to sort. Is this possible and if yes, how?
class Band
include Mongoid::Document
has_many :members, :order => :joined.asc
end

Multiple has_one association to one polymorphic model

I have two models, Address and User:
class Address < ActiveRecord::Base
belongs_to :resource, polymorphic: true
end
class User < ActiveRecord::Base
has_one :contact_address, class_name: "Address", as: :resource
has_one :billing_address, class_name: "Address", as: :resource
end
Problem is if I create billing_address for User it will be automatically set as contact_address, since the addresses table doesn't specify a different resource_type (both are User).
Can you give me some advice on how I should set up my models?
Thanks
I would say a billing address is more to do with an order than a person. For example, on one order I might want you to bill me at work, another at home.
Also, a person can have many addresses, but an address can also have many people. It is a network, not a hierarchy. The classic representation:
PARTY
id
type
name
PARTY_ADDRESS
id
party_id
address_id
type {home, work}
ADDRESS
id
suite
...
ORDER
id
date
customer_party_address_id
bill_to_party_address_id
ORDER_ITEM
id
order_id
product_id
price
quantity
ship_to_party_address_id
I choose easy way, added another foreign_key for addresses table. After that:
has_one :contact_address, class_name: "Address", as: :resource, foreign_key: :foreign_key
Single table inheritance can help you out. To get this to work you have to add a type column to the locations table through a migration (as you do with all Single Table Inheritance models).
class Address < ActiveRecord::Base
belongs_to :resource, polymorphic: true
end
class ContactAddress < Address
end
class BillingAddress < Address
end
class User < ActiveRecord::Base
has_one :contact_address, as: :resource
has_one :billing_address, as: :resource
end
For what it's worth, the belongs_to relationship name (:resource) is a bit weird. Maybe :addressable would make more sense?

Mongoid Relations 1..*

Consider the following:
class Picture
include Mongoid::Document
field :data, :type => String
end
class Cat
include Mongoid::Document
has_one :picture, :autosave => true
field :name, :type => String
end
class Dog
include Mongoid::Document
has_one :picture, :autosave => true
field :name, :type => String
end
Now, is it possible to do the following:
dog = Dog.new
dog.picture = Picture.new
dog.save!
Without having to edit the Picture class to the following:
class Picture
include Mongoid::Document
belongs_to :cat
belongs_to :dog
field :data, :type => String
end
I don't need pictures to know about it's Dog or Cat. Is this possible?
I believe you could do this if you put the belongs_to :picture in your dog and cat classes. The side of the relation that has belongs_to is the side that will store the foreign key. That would put a picture_id field in each of Dog and Cat, instead of having to store a whatever_id for each type of think you want to link on your Picture class.
No it is not. You need to have cat_id or dog_id or some polymorphic obj_id for all of them to store information about belonging of this picture.
Or how do you know wich Picture belongs to current Dog or Cat?

Resources