I have a rails app where users share specific kinds of photos. Currently the app requires photos to be categorized in several ways before they are valid, hence users must upload photos one at a time and categorize them in order to save them to the database.
Categorization takes some time, so I'd like to allow users to upload batches of photos and then come back and categorize them when they have time, but when photos are stored without being fully categorized I don't want them mixed in with "complete" photos.
I'd ideally like this to be a sort of "Wizard" system where users can upload a bunch of photos at once and then proceed through their personal queue and categorize each photo (to finish creating it) when they have time.
My question is: how would you approach a problem like this?
I've been thinking about using Single Table Inheritance to create two subclasses of Photo: IncompletePhoto and CompletePhoto. The IncompletePhoto would only require the image file itself, but CompletePhoto would require categorization. Users could view their own IncompletePhotos, but search results within the app would only return CompletePhotos.
Does that sound like the right approach for the problem I'm trying to solve, or is there a better way? I've never used STI before and I'm not sure whether or not it's a good idea.
I'd say that STI was created to be useful when you have different objects with some, but not all common properties, for the cases where you'll benefit from DRY in both database and models. I'm not sure if there is a way to correctly change the type of instance of such a model. Well, you can just modify the type column itself, but the Ruby class of the object will be the same, and so will be validations, unless you will re-fetch the model after saving and then run validations manually. The latter sounds like a dirty hack for me.
As a correct way, I'd suggest you to add complete column, and use validators in form of validates ..., :if => :complete.
Related
I'm new to Ruby on Rails. I have a relatively simple question. I'm modeling users. I want users to be able to have a short "profile message" that they can edit and that gets displayed on their profiles. Would it make sense to make ProfileMessage its own model? Or, should profile_message be one column in a table that contains user settings?
I feel like an entire model just for one string is a little bit overkill and if I start going that route, I'm going to end up with so many models that things become cumbersome.
What does the community think?
I would keep your data structure as simple as possible when starting out. For a profile message, it doesn't make much sense to have it be it's own model. Only if profile_message were to later on have it's own set of attributes and behaviors, or if users could have more than one profile message...then I would consider moving it to a separate model.
Table joins in SQL consumes a lot of resources when you are not using them properly. In your case i think that making a new model only for the one profile_message is not a good practice.However, it should be implemented inside the user/profile model.
This approach is going to make accessing the message faster, on the other hand if you are using a whole table for the profile_message will make the response time slower because you will need to look for it every time in the profileMessages table which will take more time depending on the number of entries in that table.
At the moment ’m building a web app using Ruby on Rails. I try to get my head around the data model and database part. To make it easy to understand I’ll use IFTTT as an analogy:
In the app, the user can add different recipes, for example:
Facebook — Twitter
Weather — Send email
You name it...
Of course every recipe has its own fields and options. So the user can choose multiple recipes from the library and set options to every recipe. The library of recipes is defined in code.
I have a few questions regarding this setup and would be happy if I could get some directions:
Is it smart to serialize the options of a recipe into a single database field? Every recipe has different fields and I don‘t want a database table for every recipe type.
Or is it better to create a ‘key-value’ table with all the options of all the recipes?
How to handle validation? Can Virtus come in handy?
Is a NoSQL database a good fit for these kinds of applications?
Are there best practices for these kinds of applications/data models? Any help is welcome.
Thanks!
Rens
Not sure if SO is the best place for really general questions like this but I'll take a swing
1 && 2) Personally I'd give the recipe table an action_taken field, probably as a string, and fields for all the available, resulting actions as booleans. Then the only thing you really need to be careful of is making sure the action_taken field remains uniform
3) ActiveRecord has a pretty fleshed out validation suite built in. You can validate based on presence, uniqueness, inclusion in a set of elements, etc. You can also extra validations on the database if you feel like being extra safe
4) I would use PostgreSQL, seems to be the community standard so probably the easiest to get support with if you need it
Hope this helps
been kicking this one about for a while now, and would like to get someone who knows rails to test my theory (I'm new to Rails).
In my (simplified) scenario, I want to manage a list of Users, some of which are, for example, "paid" users, some are "free" users etc, and there is a straight "isa" relationship. i.e. a paid user isa user, a free user isa user etc
To reduce redundancy and to keep it semantically correct, I want to manage all the users in one table and use a foreign-key back to the correct "type" of user, so I can create a role of the correct type. e.g. I would instantiate a User, get the id and store this in the user of correct type e.g. "PaidUser" in the "user_id" foreign-key. This gives me the ability to store specific metadata I want to store against them, and I don't have to have one table ("users") with every field for every type of user.
This sort of feels like a confusion of roles and types of users. My question is, is using the approach above going to make life difficult? Is there an accepted approach to this in Rails that I'm missing? I'm using Devise and have removed all routes except for /users/ thinking I would pass a "type" as an argument, and use that type to create the corresponding "real" type of record at the same time as the user. Is this bad practice too?
Thanks in advance
What you're doing sounds fine, but to be honest unless you have a lot of these different properties between user types I would just put them all in the same table. It's not really a big deal to have a couple of blank columns here and there, especially when it saves you from having to do a whole load of difficult stuff. If this starts to seem unwieldy then you can worry about what to do then - it would still be easy to change. You could even then potentially use Single Table Inheritance to give all the different user types their own class that inherits from the base User class, which is where you take care of all the authentication etc.
If you immediately go with something more complex then it will be much harder to unravel if it turns out to be wrong than if you start with something simple. If you go with the multi-table approach then make sure you name them sensibly. I would go with PaidUserProfile etc.
I'm making an app with Rails that, among other things, allows certain types of professionals to create an online profile. So there is an 'association' between the User and Profile model. I created the Profile model so that I can basically restrict the User model to name and registration information, and keep profile information elsewhere (i.e. 'normalize' the db as I think it's called)
However, these profiles (as is often the case, on LinkedIn, for example) contain a lot of information. For example, there will be a section for Work Experience that sometimes looks like this, where a user can add many different work experiences.
and then something similar for education
And many other different types profile information. Note also, that the ability to add to and edit these discrete categories takes place in separate forms. I can add to my work experience without touching education.
My question is, should I try to store all of this information in my Profile model? Or, would you, for example, create a WorkExperience model and do something like Profile :has_many work_experiences? and something similar with EducationExperience, or is there even another way to do it?
One of my concerns is queries on the DB. For example, in terms of performance, is there going to be much of a difference if, in the show action of the Profile controller, I do queries for WorkExperience.all, Education.all rather than storing all the information in the Profile model?. Another concern is just general code organization for profiles that can become quite large.
You'll have the cleanest code (and decent performance) by splitting out something like Experience (which will belong_to Profile), along with a type column that determines whether it's "work" experience, "education" experience, etc. That's the approach I would take, unless the different types of experience have vastly different columns.
Scenario: I have a users table in my application. I also have two subclasses of users, lets say contributors and viewers. Each user group must have an entirely different set of attributes but they both share certain user properties (login, password, name).
What is the best way to implement this using Ruby on Rails?
I think single table inheritance would leave me with too many null fields.
I think linking three tables (users, viewers, contributors) would work fine, but then when wanting to edit any information i have to do: #user.viewer, while i would love to be able to just do #viewer.
Any ideas of the best solution?
I would probably go with the three tables approach. Data integrity is king over code cleanliness.
If you want to make it look neater, put virtual attributes on the Viewer and Contributor models that make it look like the User attributes are local. You can make it a module and include it in both Viewer and Contributor models.
You can also set up an :include => :user on the default finders so that you don't get an extra query when using those fields.
I'm extremely caffeinated right now, so comment back if that doesn't make sense :)
don't compromise the database schema, make it fit best. I like the three table method. If you do the database bad, the application will have very hard to fix issues later, run slow, etc.