I have a model, Item.
Each Item has_many traits.
The traits can be many different things:
A SizeTrait
A ToppingsTrait
A FlavorTrait
etc
How can I set up this relationship in Ruby on Rails? In a normal Ruby app I could just use duck typing, but this needs to be stored the the database.
It's like the reverse of belongs_to with polymorphic: true
I would like to avoid single table inheritance as these traits, while they will share a duck type interface, will have very different functionality. This would cause a lot of unused fields in the table and that seems like a messy, confusing way of doing it.
There are a couple posts about this already on StackOverflow, but one has a different situation than mine and the other has a pretty dodgy solution, and I want to see if there's a better one.
You can't make joins across a polymorphic association. The best approach is to just buckle down with the STI as you mentioned previously. Although you may argue that you will have multiple fields witch will be null, at least rails will be able to make sensible joins to aid you in your queries.
Related
I'm using Rails 4 and am trying to implement a Notif model which should have an array of users that have seen it.
My idea is to use a has_many relationship (notif has_many :users) where I add users which have seen the notif to the users. The current issue I'm experiencing is that I cannot call #notif.users because it states column users.notif_id does not exist since I'm not using a belongs_to.
One solution is to use a many-to-many relationship; however, I'd like to avoid having to create an individual association for each user that views a notification (trying to save database space).
Is there a way to effectively have a users field without the has_many relationship? I guess I'm simply trying to store an array of user ids in my notif model.
IF you're using a relational database, although this is a correct omnidirectional relationship, ActiveRecord isn't going to play very nicely with you (if at all).
Also, it's important to note that, in the year 2015, trying to find an omnidirectional ActiveRecord workaround is far more expensive than the extra database entries.
It is technically possible - but it's not how ActiveRecord works and it won't save you money.
Not all databases actually support array types. Without array types you would have to store the ids in a string, which pretty much eliminates any effective form of querying and joins.
Even the DBs that support arrays don't really support storing foreign keys in arrays. This means you can kiss referential integrity goodbye. Indexing arrays might not work either.
Add to this the fact that you can't use Rails associations without major hacks.
I hope you realize by now that it's a pretty stupid plan to save money. Especially since database space is cheap compared to developer time.
I have 3-4 different types of clients for a photo site. Musician, wedding, portrait, and general with the possibility of adding more types. The idea is each type will have a shared set of attributes such as name email etc. but each will have their own too.
Musicians will have band name, members, genre, while wedding will have venue, coordinator details and so on.
I think this is the right way to go about it, correct me if there's an easier way to track multiple shared and unique attributes.
I was reading up on single table inheritance and one place said to use it only if the models have the same attributes but different behavior. How can I structure my models to meet this? From a more generic OOP standpoint this makes a lot of sense to me, but I'm having doubt's from that clause of STI.
Your use case sounds like a good one for STI. The key thing is that the children share some attributes with their siblings, not all attributes. I found this overview helpful:
http://samurails.com/tutorial/single-table-inheritance-with-rails-4-part-1/
I'm facing a conception problem in developping a website for my videogame.
I have a Model named VideoLink which contain a title, a description and a link to a webvideo (for example youtube).
I have other models such as User, Map, Mission etc.
I want my users to be able to say that a video was made on those maps, during this mission, and those users appears.
I'm wondering if I should go with associations (with has_many relationships) or tagging (with acts_as_taggable_on and 3 attributes maps_list, users_list, mission).
I find associations a little heavy for this as it is a tagging thing not really a relation.
But maybe I'm wrong and tagging could not be the best choice.
Which solution you think is the most relevant to my situation ?
If you have other solutions or questions please tell me, I'm in fact a noob at ror ^^
Thanks for any help.
You would probably get a lot more out if it using associations. If you want to do things like easily generating links to view more details about videolink resources, associations are definitely the way to go. You can do this without associations, but honestly it's a lot less trouble in the long-run if you simply throw a few associations into your models. You could probably build your own tagging solution more specific to your problem-domain easily if you have associations in place for all your models as well. I would recommend taking this option especially so if you're new to ruby on rails, as ActiveRecord associations are an integral part to RoR and it could be a great learning experience. Check out Why associations? for a little more detail on how associations can be useful, the rest of the guide is also a must-read if you haven't already.
If you don't really see value in links and being able to easily query a video for related resources, go with acts_as_taggable_on.
Given you have to implement a news feed like the one seen in social networks, ex facebook.
Currently I'm using a News class which has a polymorphic assocation which can be of any kind like Image, Comment, Friendship, GroupMembership, etc. Whenever an Object is created, as News is created too. It's working fine with AR(ActiveRecords) but I get into trouble when I'd switch to DM(DataMapper) or Sequel as both don't natevily support polymorphic associations and discourage it's usage.
One workaround would be to use a big SQL clause with lot's of UNIONs to merge all the different tables which should be considered as news. But this has some drawbacks, escpecially performance would be terrible.
So I wonder how to solve without polymorphic associations while still getting good performance and no other drawbacks, like having the possibility of adding meta data to a news?
Disclaimer: I'm the lead developer of Sequel.
The best way to go about it usually depends on what types of things you want to do with the data. One way to go about it is to have foreign key columns for all possible relationships:
news:
id
... (Other columns)
image_id
comment_id
friendship_id
group_membership_id
There is really no performance difference in doing things this way versus having a generic foreign key and storing a class name. For lazy loading, you just pick the one foreign key field that's not nil/NULL, and choose the appropriate association to load. For query-per-table eager loading, you just load all associations at once. This also is more flexible in that you can eagerly load using JOINs, which isn't possible with the polymorphic approach. Plus, you get the benefit of real referential integrity.
The one downside is that if you want to add more association types in the future, you need to add foreign keys to the table.
Here's a gem to maintain the referential integrity of Polymorphic Associations at the database level in Rails:
https://github.com/mkraft/fides
As of this posting there are adapters for SQLite3 and Postgresql.
Disclaimer: I wrote the gem.
I've just been reading Chad Fowler's blog post about 20 Rails Development No-Nos. On Single Table Inheritance he comments:
The storage of a column called “type” which holds a class name is a pretty good indicator that something fishy is going on. It’s fishy but not always bad. I think, though, that any time you use it you should ask yourself more than once if it’s the right solution. Databases don’t do what they do best as well when you have lots of STI and polymorphic associations.
I'm writing a blog application and I'm considering using STI for the comments that can be made on a post and for the contact messages that visitors can post if they want to get in touch with me. My Message model will inherit from my Comment model. They both share common attributes, except that Message will have an extra subject field. Another commonality is that both will be submitted to Akismet for spam checking.
Rather than just ask myself more than once if it's the right solution as Chad suggests, I thought I'd get some opinions from the Stack Overflow experts as well! Does what I'm proposing sound like a good fit for STI?
I've used STI a number of times. Consider a CMS which might have Page, NewsItem, BlogItem etc.
They could each descend from a common class which in turn inherits from ActiveRecord. The table for each would be the same (title, body, tags, published_at) but each model might have different associations, or different statuses, or a different workflow so each has custom code in their own class. Yet they all share a common table and parent class. It also allow me to use the parent class to do a cross class search and have the resulting Array of records automatically type cast.
There are other ways to tackle this and maybe not the best example but there are certainly times when STI is handy for situations where object behavior may differ but persisted state is the same. Of course you have to be sure this is also true in the future.
In your case comments and contact messages are different. It sounds like there is there no benefit by having them in the same table. Maybe put shared code in a parent class or better still in a module in /lib.