reviewing the fields I have in a model in rails - ruby-on-rails

It seems like a silly question, but anyway:
I have a model with lets say 10-12 fields (columns) added in different migrations.
When I write code now (model, view, tests) I want to have a list of the column names.
Is there a good way to do so? (other than going to the DB manually and getting the column names)
It seems like an action the developer does quite often, or is it just me

Simply use ActiveRecord::Base#column_names:
Model.column_names

You could do something like:
ModelName.new.attributes.keys

Related

ActiveRecord: Search multiple models for a list of words

I have a search controller where I want to search a number of different models.
So say I have this query: "Foo bar baz". Then I want to have the following queries:
Model1.where("name like '%foo%' or name like '%bar%' or name like '%baz'").offset(o).limit(l)
Model2.where("title like '%foo%' or title like '%bar%' or title like '%baz'").offset(o).limit(l)
Model3.joins(:sources).where("sources.name" => [source1, source2]).where("name like '%foo%' or name like '%bar%' or name like '%baz'").offset(o).limit(l)
Most important is that I want to do it safe (no SQL injections) but it would be nice if I could keep it DRY and pretty as well. I am using Rails 4 but I am very new to it. I have seen that there's something called "Concerns" which may be something to use?
Thanks!
Dependencies
You'll probably be best using one of the search extensions for Ruby stacks:
Sunspot Solr
ElasticSearch
Sphynx
As a disclaimer, I've never used any of these in production, but from my understanding, each of them will "index" data in your application, and then perform a search based on that indexed data
--
Indexing
The bottom line is if you want to search multiple models, you'll be best harnessing an index-based search system. This will take all the data you want to index, and put it into a manageable, searchable format that you can then call when you need.
As far as I know, sunspot works very well in this regard (indexing your data). The trick is to include all your models in the Sunspot settings, from which you can then pull the data you need.
There's a great Railscast about this here:
I don't have any live code for you I'm afraid - if you need more ideas, though, I'll gladly come back with them

Which approach should I use to store translation of products in database?

I'm creating an application where products will be created by my customer (something like an e-commerce website), so I obviously require translated descriptions stored in database, I can't force my customer to learn git/yml.
I have two ideas on how to correctly localize descriptions (and eventually product name) and store them in database, but if there is a well-known approach that I should use, I would be really happy to know it.
The first idea seems the most logical for me, but I would like to make it "transparent" to me, I don't want to write joins everywhere, so some suggestion on how to achieve this, if it's the correct one, would be appreciated.
Idea 1:
Create a database table products (with name and description field set maybe to the default locale language), then a products_translations table which contains a table structured in this way:
products_translations
- id
- locale
- product_id
- name
- description
As an example: product_translation: { id: 1, locale: 'en', product_id: 3, name: 'toy', description: 'play' }
But I want to access to translations without the requirement to write a lot of IFs everywhere. So if I write product.name it should return en or it based on current locale.
Bonus: Are there any gems that can help me to achieve this?
Idea 2: The other idea is to have a table with name_locale1, name_it and so on, but I don't like this approach because will pollute my model objects with fields and I will have a giant table.
However, in this way I can avoid join on every query for that object.
If there is a greater approach which I don't know about (a database pattern or similar), it's ok that too, I'm not forced to strict to only these two ideas, however I have to choose between the two and I really don't know which could be better.
Important: I would like to keep translations stored in yml files, except for dynamic contents, which obviously require translations in database.
I agree with PinnyM that the first approach is the better of the two, but rather than implement your own schema, I would highly recommend you implement Globalize3 where most of the structural decisions have been taken for you (and by Mr Fuchs himself, no less). Also, with the rails helpers, you just call something like product.name on a model instance and the gem will figure out how to display it in the correct locale, awesome!
The first approach is the recommended one. As you surmised, the second approach is not as clean and requires more work on the coding end with no real gain since you still have to join on this monster table. To the contrary, the first method requires at most one join, while the second approach requires a join on each attribute you may want to add localization support.
You can simply append a scope on all your product calls such as:
scope :for_locale, lambda{|locale| joins(:product_translations).
where(product_translations: {locale: locale || 'en'}) }
and pass in the session locale (or wherever you are storing it).

Rails find_by_email multiple tables

I am working on a rails application and i have 3 different user types. These users are potentially very different, so i created models for each of them. Now, they should be able to login thru a single form. So basically i want to say something like 'find_by_email("some_email")', but search over all three tables. It seems, though, that Rails expect you to call 'find_by' with a specific model, like Admin.find_by(). Any suggestions?
Try something like this and assuming that that the email is unique across all the tables
[Model1, Model2, Model3].each do |model|
break if model.find_by_email("email#email.com").present?
end
Hopefully this is early in your development, but the current structure may not be the best possible route. How many different columns are NOT shared by each of the user types? You may want to use a "user role" system, and have that simply be an extra column on your user table.
Than, you can use something like CanCan to manage those roles and what/where they may access.

Rails fixtures or similar for creating data within an app

I want to populate a preferences table when a user is created. I can make a lash up version within the controller easily enough but would like something neater.
Can one do the same sort of thing with fixtures within a running application? If so how?
You could search for a gem. I've used https://github.com/FooBarWidget/default_value_for some time ago for a similar thing. It's a nice and clean solution.
In the end I simple defined an array in the model and array.each -ed it. Not perhaps the most elegant but still have all the values in one place for editing.

Is a table with constant values in rails a good idea? or is a constant hash smarter?

I am creating an application where I need to categorize one of my models. There are five categories and they will not change, at least not for now. The object can only have one category at once. My two ideas are:
Create a whole table for adding the categories and add them in the migration file. I would then store the category id in the db for my object. Read about this causing problems with testing so I'm not sure. And, it seems a bit overkill.
Add a constant hash in my model for hosting the categories. I would then store the int key in my object.
Is there any better way I have not thought about? Are there any plugins for creating enums in rails?
Thanks
I have used this plugin https://github.com/adzap/active_enum some time ago and I think it works OK. You should definitely try it.

Resources