Models in Rails are implicit, is this an annoying thing? - ruby-on-rails

Considering models in Rails:
class Organization < ActiveRecord::Base
belongs_to :OrgType
end
Does it bother you that models in Rails don't include the fields that made the entity?
I know this is done for DRY's sake but you have to check the data base tables schema every time you want to check model's fields.

If you prefer a declarative style of ORM model, you might want to check out DataMapper or Sequel, both of which are easy to plug in to Rails 3.

Not annoying for me... ever since I started using the annotate-models gem to automatically add comments to the top of my model files, listing the fields associated with that model.

I was listening to a podcast a few months ago where the guy hosting the cast and the guest were advocating that Rails should take this path, and do away with migrations. The guy kept repeating "migrations must die", suggesting there be a way to specify your schema on the model instead.
I cannot disagree more, and I hope Rails never takes this path. Not only is it not DRY, but I like the fact that Rails encourages you to be aware of your own databases schema and structure.
In addition, there would be no way to keep a history of your schema if models were what controlled it, without having them be extremely cluttered. Migrations are essentially version control for your database that evolves with your application...and I wouldn't want to not have that.

Let's assume that OrgType has a field called position. This is common when you want to present a select list to the users who will be choosing a type. It's highly unlikely that your Organization will ever care about this field. Now extrapolate this to other related models with fields that other models don't care about, and add in the fact that if you ever wanted to change one of these fields you'd then have to hunt down each declaration of them, not just each place where they are used.
It's a mess.
Open up your db tool and look at your fields when you want to know what they are. Keep your models clean and readable. If you see code like this:
organization.org_type.name
It's pretty obvious that OrgType has a name field, without having to look it up, and without having to wade through configuration clutter in each model.

Related

Data model and storage for Rails app

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

Why does rails generate add timestamps to models by default?

I would expect that most models do not require information about when they were created and updated as a necessary feature of the model. Indeed, the getting started guide doesn't use or mention them. So what is the reasoning behind creating created_at/updated_at fields for models by default?
You may disable them from being created in your migrations if you would like. But to answer your question, you may be surprised how many models tend to have some sort of need to use data from the time stamps in some way, whether thats setting the default scope of that table, using the data to expire certain things, etc... They are included by default because they are useful and convenient to a lot of people, but if you are positive you don't need those feilds, feel free to get rid of them.
A timestamp is added to make it easier for user. A timestamp can be used to understand when what model was created and also to distinguish between different databases

Would it be crazy to use a (serialized) array instead of a join table to link two database tables?

I'm using Ruby on Rails to develop a web application.
I have a wiki article system as part of my project.
As part of the wiki, articles can be linked to authors, and those links also need to be tracked by the revision system. Authors is an attribute of the Article as a whole, and not related to who enters particular Revision, and is a list that is updated over time along with the other wiki attributes.
Right now, I've got it setup and working as follows with a central Article model, which has_many Revisions, which has_many AuthorCredits:
class Article
has_many :revisions
end
class Revision
has_many :author_credits
end
class AuthorCredit
belongs_to :revision
belongs_to :author
end
While this works, it's pretty awkward, in that I have to build a whole additional set of joins (in the form of AuthorCredits) each time I make a new Revision, no matter how small. Furthermore, there's quite a bit of additional complexity inherent in using this approach with my actual models that makes this really quite complex and fragile.
I'm thinking about reducing the whole thing into just the Article model, and adding a serialized Array to the model that's a list of authors. Essentially, I'd be moving the join table into a serialized text field. Then I could just slap on an out of the box revision tracking plugin like Paper Trail, and have an extremely clean model schema.
Has anyone ever done anything like this before? I've never heard of it, so I'm worried this might be a crazy idea, but my current situation is so complicated/fragile that I'm seriously tempted.
One huge loss I see right off the bat is that I wouldn't be able to call database operations anymore like join directly on my data. I assume this would also kill my ability to use convenient Rails methods like belongs_to :authors. Together this means I would entirely lose the ability to go in the opposite direction, and see all things credited to a particular Author, and that alone might kill this entire idea unless I can figure out a way around it. I might compromise by having a set of joins for the current AuthorCredits, but store them also as a serialized Array so that it's still tracked in that manner, but then reversions become problematic with off the shelf solutions, and I'd have to modify Paper Trail or whatever I use to handle rebuilding or removing AuthorCredits when reverting.
How would you handle modeling a system like this?
Yes, its a bad idea! You lose out on the power and flexibilty of having a database plus you have an excedingly awkward data structure to manage.
You could perhaps adjust your model.
Change the relationship so that "AuthorCredit" is a "hasmany" of "Article".
Then you can then either add a "from revision" to "to revision" attribute to the relationship or just accept that you only want a list of current authors.
You would only need to add an Author Credit on the revision they first appear in and you can mark them as dropped by merely setting the "to revision: attribute when they are dropped.

RoR table inheritance?

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.

Namespaced models in Rails: What's the state of the union?

Since the beginning, Rails has had issues with namespaced models. As time went on, pretty much everybody gave up on using it. Myself included.
With Rails 2.3 out, I'd like an update on the situation. Specifics questions I have in mind are:
first off, is it good to go?
table naming, what rule to follow?
associations, how to declare them with the least verbosity? how to name foreign key columns?
auto-requiring, does it work if you put the model files in a subdir matching the namespace? or, how to name and where to place the files?
generation, does the model generator handles namespaces successfully and correctly?
generation, how about the scaffold generator, which includes controllers?
any incompatibilities/quirkinesses one should be aware of?
The best writeup I've seen on the issue is from Strictly Untyped. To my knowledge 2.3 hasn't resolved any issues, which means they're still unreliable.
We recently had a big debate about this inside our company. I think at the end of the day, we figured that if you can't namespace tables inside a database, it makes no sense to namespace the models. We settled on prefixing our models (User, UserAddress, UserEmailAddresses) and putting them into the users directory, then using:
config.load_paths << "#{RAILS_ROOT}/app/models/users"
to load the models. To control the verbosity in our models, we do this frequently:
has_many :addresses, :class_name => "UserAddress"
When generating, we create it as if there was no namespace (script/generate model UserAddress) then manually copy it to the user directory.
Shrug. I guess in the end all this really gives you is a cleaner directory structure, which is actually more trouble for a VIM user like me, but nice for TextMaters.
I would still stay away from it. Anything gained (which I'm not sure what that would honestly be) would definitely be lost when you consider the hassle and loss of brevity and clarity in your code.
My latest app has 87 resources, and includes administrative features all over the place. I see no need for namespacing, IMHO.

Resources