Rails has_many without a belongs_to - ruby-on-rails

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.

Related

Ruby on Rails has_many polymorphic

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.

Rails Multi Tenant SAAS application with user customizable fields

We are building an a SAAS application. We need to allow customers to customize the fields of a certain model. They should be able to add or remove fields. This application is basically an asset management where customers should be able to customize the attributes of an asset.
We have tables for the assets. And these tables have multiple attribute tables like warranty, vendor, maintenance etc.
i.e
class Computer < ..
has_one :warranty
has_one :vendor
end
We have default set of attributes there but a customer should be able to alter the fields.
How do we achieve this?
Ok heres what I know. For Multitenancy we can use scopes, or multiple dbs or the awesome PostgreSQL's Schemas. But how do we implement custom fields for each customer.
Should we go for NoSQL? or should we use RDBMS for base tables and NoSQL for attribute tables?
Whats the right combination or solution or architecture for a scalable SAAS app with this requirement?
It depends on use cases and you are many choices. But, in my opinion, it's better to avoid using two kinds of db together when possible.
If you are not using PostgreSQL and no heavy queries needed for those attributes, ActiveRecord serialize can help. It utilize a text field to stored serialized hash and arrays. Nesting acceptable, speed slower.
If all of the attributes are one level key/value pair, say, warranty: 18 months, vendor: 123, then "hstore" is a good choice, built-in in PostgreSQL.
"hstore" is flexible and fast, but not suitable for nested hash. And there is a great gem dealing with it: https://github.com/diogob/activerecord-postgres-hstore
If nested hash, PostgreSQL "JSON" fieldtype may help. http://www.postgresql.org/docs/devel/static/functions-json.html It's new and I havn't used that before, just heard it's more stable and practical.
I think those choices should be enough to solve your problem. If they still can't do, maybe you can consider MongoDB.
You should definitely go for NoSQL like MongoDB. The base tables like user, profiles and other stuff which needs transaction processing should go in RDBMS.

Using join table in a one to many association for legacy tables

I'm trying to marry a rails app to a related (and seriously crufty and wet) PHP app but having both apps share a database. So far it's working happily. I've encountered a case where I need a one to many relationship between a new model and a legacy one. Normally I'd simply use:
class LegacyModel < ActiveRecord::Base
belongs_to :new_model
end
class NewModel < ActiveRecord::Base
has_many :legacy_models
end
But in order do this I'd end up having to add a column to the legacy table and I'd rather not do that; the legacy app is fragile enough that I really don't want to risk altering its tables; just use them in a read only sense. So I was considering using a join table where the new_model_id is unique and the legacy_model_id is not. This feels like I'm going off the Rails but I want that association fairly bad so I'm wondering if:
1) Is this an acceptable approach?
2) Are there any more better solutions?
Please note that my sample code is pseudo-code and not representative. I just want to get the idea across.
Thanks in advance for any help you can give me.
That's a perfectly fine approach as far as I can see. Even if the model you were trying to connect to was a part of your current Rails app, having an explicit join table has many advantages (like being able to - either right away or later on - add more columns to it in order to add and capture more data).
I myself am working on something similar, but the other database I am touching is not a legacy, but quite new, except that I too only want to connect to it in a read only fashion, and so I make that similar join table. Nothing wrong with that!

Where to set up foreign key relationships in rails app with has_many through

I am setting up a simple has_many through relationship. I was wondering if there are any best practices I should consider when setting up the foreign key relationships.
The application is designed to allow users to create items and ads, where a listing model is used to connect items with ads (the listing model also has timestamps and an order field).
The main question I have is: which models should belong_to the user model? I was thinking that the simplest solution is to have listing belong_to user. That way I can use the has_many through relationship to figure out which items and which ads belong_to each user.
However, it occurred to me that this could leave some holes depending on what work-flows I want to make possible. For example, what if a user wants to create a bunch of items before creating an ad which has those items? What if a user creates an ad before having created any items?
Based on the above, I was thinking that maybe I should just make ads and items belong to user. If I do that, is there any obvious reason to also make listing belong_to user? I was going to do that, but somehow it just looked redundant to me.
This seems like a pretty typical situation to encounter in a rails app, so I was hoping somebody with experience has been here and might be able to share some insight.
Thanks!
I'm trying to understand what you have:
User
Ad
Item
Listing
Where Listing appears to be some kind of join model that relates an Item to being in an Ad.
I don't see much of a wrong way to do this. I suppose the most normalized way of doing this would be to just have an Item belong_to a User, and get the Listings and Ads through that. But you'd be paying a price there too, both in having to write annoying code and having to perform multiple joins to get your Ads.
The opposite extreme is just to have everything belong_to the user. You have an extra column in 2 of your models, but then you also have much simpler relationships. You also wouldn't have to worry about what workflows your users are allowed when designing your schema.
Even if you mess up and leave out user_id fields in your models, it isn't terribly hard to add those fields later using migrations.

how to avoid polymorphic associations

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.

Resources