I've recently begun playing around with MongoDB on Rails through use of the MongoMapper gem. I was wondering if there is some sort of way to have a class/object/collection be both a Document as well as an Embedded Document. I want the same entity to be both included/embedded in other documents, and also be able to exist on its own as an object.
Is this possible? Am I tackling this problem the wrong way? Any discussion/advice would be greatly appreciated as resources on the web seem low for this stuff right now.
I have a very similar usecase and the solition was to have (using your entity names):
a collection with People
a embedded model BusinessPerson that belongs_to_related :person
a collection with Businesses that embeds_many :busiess_people
The idea behind this was that I have extra fields in BusinessPerson that may not apply if the Person also run a different business. Let's say the role in that business, an email address or the share of it.
No you might say getting the business a person might look hard, but it isn't:
class Person
def businesses
Business.where('business_people._id' => self.id)
end
end
Related
I'm building a Rail 3.2 app that has some complex data relationships. I'm wondering what is the best way to structure the database.
The data I'm trying to model coud be compared to elements of Facebook.
For example, there are items that a user can create:
comments
photos
posts
status
updates
Each of these items can belong to a
user
business
location
So for example "User A took a photo at MacDonalds in Paris".
I want to show an activity stream on each user, business and location page.
The way I've thought of doing this involves a two way polymorphic relationship.
one for activity:
class ActivityFeed
belongs_to :feedable, :polymorphic => true
end
class Comment | Photo | Status
has_many :activity_feeds, :as => :feedable
end
and one for ownership
class ActivityOwner
belongs_to :ownable, :polymorphic => true
end
class User | Business | Location
has_many :activity_owners, :as => :ownable
end
Then activity_owner would belong to activity_feed, and activity_feed would have many activity_owners.
I hope that makes sense?
Is this a good way to tackle this case? Are there any performance issues I should be thinking about? Is there a better way?
A followup question: using this approach, is it possible to map the same model to a polymorphic relationship in multiple ways. For example a user could be an owner of a photo, and they could be a tagged user.
I'm stil trying to learn Rails, and I'm struggling to get my head around this issue. I'd really appreciate opinions, experience and ideas from others, as well as any pointers to useful information or guides.
Thanks!
http://blog.smartlogicsolutions.com/2008/06/13/ruby-on-rails-polymorphic-association-benchmarks/
it is old a little bit but still actuall
no big drawbacks if u r using right indexes, just less columns in your db
Interesting, Have a look at Polymorphic Association (revised) by Ryan Bates. I think it will be a perfect approach to what you are trying to do. Nice and clean too
This is more of a general design question, but it will be implemented in RoR to which I am very much a newcomer. Also, I think this is my first question so please be gentle :)
The scenario is:
I have an Asset model. Each asset is located in a particular room, so I would also like a one-to-many relationship with a Location model. Simple enough. However, some rooms (Locations) also go by an alias (eg. 123 is aka Library). When a user wants to update information about a particular Asset, I would like them to be able to just search without worrying about whether they know the exact room number, and be shown a list of assets in that room.
To clarify, there could be more than one alias.
So the question is:
Would you recommend an Alias model for which a Location would have a one-to-many relationship? Or, would a self-referential (sort-of hierarchical) association be better? Or something else maybe? From what I can envisage, the former would require querying columns on different tables for the same sort of information, and the latter just doesn't seem right (an Alias is not the same as a Location).
This might be a good area for using the tagging plugin acts-as-taggable-on:
https://github.com/mbleigh/acts-as-taggable-on
In your model you can do:
class Location < ActiveRecord::Base
acts_as_taggable_on :aliases
end
Then in your controller do:
Location.tagged_with("library", :on => :aliases)
I'm still learning Ruby, and get caught up in alot of the 'magic', wanting to better understand what is actually happening, and making sure that I understand what it is doing.
I've got a user, and each user has entries.
In my user class, I have
has_many :entries
and in my entries class I have
belongs_to :user
I was expecting that the entries table would have a column for users, but I'm not seeing that when I 'describe' the database.
How do I know, or how does Rails know which user the entry is connected to? Or do I need to create a field myself to do that?
It seems strange to me that we have all these 'belongs_to', etc. yet it isn't explicit how that connection is made.
This is a common misconception. Associations do not create the database tables for you. Instead, you have to create them yourself. What you need to be careful of, is that an Entry model would have a user_id field, in order for the association to fully work. I truly would not want to advertise or anything, but i have created a blog post that can help you quite a lot i think :
http://www.codercaste.com/2011/02/06/rails-association-in-plain-english-what-i-wish-i-had-known-before-i-started/
I'm designing a ruby on rails app for a pharmacy, and one of the features is that there are stores who have pharmacists who work there. In addition, there are pharmacists, who can work at many stores. This sounds like a job for HABTM, right? Well, being the novice I am, I manually designed a workaround (because I never heard of HABTM - I basically taught myself rails and never got to some of the more advanced relationships). Right now, when a pharmacist is saved, there's a couple of lines in the create and update action of the pharmacists controller that turns the stores that they work at into a string, with each store_id separated by a comma. Then, when a store is displayed, it does a MYSQL request by
#pharmacists = Pharmacist.find :all, :conditions => "stores REGEXP '#{#store.id}'"
Would moving this system over to a rails based HABTM system be more efficient? Of course it would require less code in the end, but would it be worth it? In other words, what benefits, other than less code, would I get from moving this association to be managed by rails?
The benefit is that you will be using the right tool for the job! The whole point of using a framework such as Rails is that it helps you solve common problems without having to re-invent the wheel, which is what you've done here. By using associations you'll also be using a relational database properly and can take advantage of benefits like foreign key indexing, which will be faster than string manipulation.
You should use a has_and_belongs_to_many relationship unless you need to store extra attributes on the join model (for example the date a pharmacist started working at a store) in which case use has_many :through.
Using Rails associations will give you all the convenient methods that Rails provides, such as these:
# Find the stores the first pharmacist works at
#stores = Pharmacist.first.stores
# Find the pharmacists who work at a store
#pharmacists = Store.find_by_name('A Store').pharmacists
A Guide to ActiveRecord Associations
I am currently working on a Ruby on Rails app which will function in some ways like a site-specific social networking site. As part of this, each user on the site will have a profile where they can fill in their contact information (phone numbers, addresses, email addresses, employer, etc.).
A simple solution to modeling this would be to have a database column per piece of information I allow users to enter. However, this seems arbitrary and limited. Further, to support allowing users to enter as many phone numbers as they would like requires the addition of another database table and joins.
It seems to me that a better solution would be to serialize all the contact information entered by a user into a single field in their row. Since I will never be conditioning a SQL query on this information, such a solution wouldn't be any less efficient.
Ideally, I would like to use a vCard as my serialization format. vCards are the standard solution to storing contact information across the web, and reusing tested solutions is a Good Thing. Alternative serialization formats would include simply marshaling a ruby hash, or YAML. Regardless of serialization format, supporting the reading and updating of this information in a rails-like way seems to be a major implementation challenge.
So, here's the question: Has anyone seen this approach used in a rails application? Are there any rails plugins or gems that make such a system easy to implement?
Ideally what I would like is an acts_as_vcard to add to my model object that would handle editing the vcard for me and saving it back to the database.
vCard is good for an API, but for the actual database I would use a 1-many design. Each person can have many phone numbers, addresses, email addresses, past employers. For current employer, you could do a 1-1 relationship. I think your aversion to joins is misplaced. With proper indexes, performance should be fine. Implementation will be much simpler than if you are constantly serializing and deserializing a denormalized string representation. You won't have to reinvent the wheel as you're contemplating.
1) if you do want to go the serialization route rails has built in support for storing a hash
from http://api.rubyonrails.org/classes/ActiveRecord/Base.html
class User < ActiveRecord::Base
serialize :preferences
end
user = User.create(:preferences => { "background" => "black", "display" => large })
User.find(user.id).preferences # => { "background" => "black", "display" => large }
if you use this technique I would put the serialized field on its own model/table object, otherwise it will be included in every User find call, which is not ideal, maybe
class User < ActiveRecord::Base
has_one :contact_info
end
class ContactInfo < ActiveRecord::Base
has_many :users
serialize :data
end
# ...
user.contact_info.data[:phone_numbers] # => ['999 999-9999', '000 000-0000']
2) or if you want to go the noSql route rails has support for mongodb, you would basically embed the contact info into the User model/document
http://www.mongodb.org/
http://railstips.org/blog/archives/2009/06/27/mongomapper-the-rad-mongo-wrapper/
https://mongohq.com/home
3) or just go with the additional tables, it's not as bad as it seems, rails migrations can help a lot here with changing requirements