How to get record by ripple many association? - ruby

I want to save data into riak by ripple https://github.com/basho/ripple , and I create one model:
class Person
include Ripple::Document
property :name, String
many :friends, :class_name => "Person"
end
If there are two person model instances, how to know one person is other's friends or not ? like:
person.friends.get(somekey)

As person.friends is an array you can call it like this:
person.friends.include? otherperson

Related

Setting up a many-to-many relationship in Active Record

I have two models: meal_plans and dinners. Each meal_plan will have a week's worth of dinners, and each dinner will be on, potentially, several meal_plans.
I'm wondering what the best approach is to save 7 dinner IDs into a meal plan. Initially, I was just going to save an array of dinner IDs into a meal plan's params with a helper:
def create_week_of_meals(week)
ids = []
week.each {|dinner| ids.push(dinner.id)}
return ids
end
With strong params:
params.require(:meal_plan).permit(:user_id, :meals)
This works alright, but it leaves me with a string of meal_ids which I would have to turn back into an array and then query Dinners for each one of those dinner ids. Is there a better way of doing this? I've seen a lot of references to rails accepts_nested_attributes_for but from what I can tell that mostly deals with saving some attributes from another model into the current record, whereas I'm looking to save a reference to several models.
I am familiar with has_many_through relationships but it seems like a lot of overhead to create a separate model and seven new records for each meal plan just to attach some dinner_ids to a record.
class Dinner < ActiveRecord::Base
has_many :meal_plan_placements
has_many :meal_plans, through: :meal_plan_placements
end
class MealPlan < ActiveRecord::Base
has_many :meal_plan_placements
has_many :dinners, through: :meal_plan_placements
end
class MealPlanPlacement < ActiveRecord::Base
belongs_to :dinner
belongs_to :meal_plan
end
This should work, but I haven't actually run it locally, so you should play around with it. You can also read more about the through option.

Access attribute in Active Record 'through' association object

I have two classes, User and Product in a 'many-to-many through' association, using the class Prole (for product role).
class User < ActiveRecord::Base
has_many :proles
has_many :products, through: :proles
end
class Product < ActiveRecord::Base
has_many :proles
has_many :users, through: :proles
end
class Prole < ActiveRecord::Base
# has an attribute called 'role'
end
prole has an attribute called role which I'd like to use to qualify the user-product association.
The association works fine, but I can't figure out how to access the role attribute after creating the association. For example, if I do:
user.products << product
how can I access the attribute in the prole object just created?
I guess I could iterate through the prole objects and find the correct one, but I'm hoping there's a cleaner way.
Is this possible? Any hints?
TIA.
I was hoping for something a little more direct, but here's a
POSSIBLE ANSWER:
prole = Prole.find_by user_id: user.id, product_id: product.id
or even better
prole = user.proles.where("product_id = #{product.id}")
After some testing, it looks like the easiest way to grab specifically the Prole object that was just created is by querying by the two foreign keys directly against the Prole model, as suggested in your possible answer.
Prole.find_by(user_id: user.id, product_id: product.id)
If you want it as an association on the user object, you could use the includes approach to do eager loading, but it will still load every prole for the user in question
# specifying proles: {product_id: product.id} in the where clause here
# only limits users retrieved, not proles
user = User.includes(:proles).where(id: user.id)
# eager-loaded prole array
user.proles.find { |prole| prole.product_id == product.id }
See this answer for more info on that. But it looks like your possible answer is the cleanest way.

Mongoid: Retrieves all embedded documents

Suppose we have these models:
class Person
include Mongoid::Document
embeds_many :albums
end
class Album
include Mongoid::Document
embeds_many :photos
end
class Photo
include Mongoid::Document
end
What I want is to retrieves all Photo of a particular Person. Is there a mongoid/mongodb shortcuts or the only way is to iterate over person.albums and store all album.photos in a new array?
Thanks.
You have 2 ways to do this, one is through Mongoid, which, AFAIK, will inflate all objects.
Something like:
Person.only("albums.photos").where(id: '1').albums.map(&:photos).flatten
Or you can do it in Moped(driver) which will return only an array of photos.
Person.collection.find(id: "1").select("albums.photos" => 1).
first["albums"].map { |a| a["photos"] }.flatten
On the DB load, both dont make any difference, as they will yield the same query, only difference is that the first one will create way more objects than the second one.

Rails 3 scope only select certain attributes for a has_many relationship

This looks like it should be something pretty easy but I can't seem to get it to work. I have a model with a has_many relationship and I'd like a scope on the parent that allows me to select only certain attributes for each.
An example:
class Bakery < ActiveRecord::Base
has_many :pastries
scope :summary, select([:id, :name, 'some option calling pastries.summary'])
class Pastry < ActiveRecord::Base
belongs_to :bakery
scope :summary, select([:id, :image_url])
I'd like to be able to call something like Bakery.first.summary and get a Bakery model with only the id and name populated and for each pastry in it's pastries array to only have the id and image_url attributes populated.
You could do this, but it won't affect the SQL queries that are made as a result (assuming you're trying to optimise the underlying query?):
class Pastry
...
def summary
{
:id => self.id,
:image_url => self.image_url
}
end
end
class Bakery
...
def summary
pastries.collect {|i| i.summary }
end
end
This would then give you an array of hashes, not model instances.
ActiveRecord doesn't behave how you're expecting with models - it will fetch whatever data it thinks you need. You could look at using the Sequel gem instead, or executing a raw SQL query such as:
Pastry.find_by_sql("SELECT id, name from ...")
But this could give you unexpected behaviour.

multiple belongs_to for a model

I have this model "Comment" which is given by a model "User" for a given "city" and "department".
While creating the schema for table "comments", I put in columns city_id, department_id and user_id which should act as foreign keys to respective ids in tables cities, departments and users.
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :city
belongs_to :department
end
Cities and Departments are independent tables which are populated with reference data (which would be used to populate in the forms.
When I try to access comment.city.name, I get a "undefined method `name' for nil:NilClass".
Table cities is defined with columns -"id", "name" and "symbol".
What is the root cause of this error?
What else do I need to do ? I have tried even by putting has_many :feedbacks in class City and class Department (even though it should not happen because they are independent of comments). I am missing something basic here, it seems.
Thanks,
Ashish
I think you need a has_many to go with every belongs_to. So each of your classes that comments belong_to (User, City, Department) should have
has_many :comments

Resources