Rails, get column name of value - ruby-on-rails

This might be a little odd, but how can I get the column name from object in my model?
For example, I have a table which happens to have all 50 states in it as separate columns (I know, I know that could be way more efficient), so they look like:
al_allowed, ak_allowed, etc...
These columns are booleans, but I wanted to know in my model how to get the column names?, for example if for a particular record (in this case Campaigns), I want to see which states are checked off, and if they are True, I want to push the states abbreviation(the column name) into an array.

You can get an array of column names from an ActiveRecord model by calling the column_names method. It's a class method, not an instance method, so you would use Campaign.column_names.

Related

How to get right values from array thats values are in other table

I have the list of records saved as array in database like below:
---
- '9'
- '10'
- '11'
These are saved in option_ids column in table.
I have another table in which they all are present like below.
What I need to do is to print the values text like speak well if its id is present in options_ids column. So, what will happen is, if options_ids contains 9,10,12 etc so we will print data from other rows table like speak well, read well, listen well.
Assuming your "other table" is class OtherTable and assuming your fourth column is called text then you'd want to do
options_ids.map{|option| OtherTable.find(option).text}.join(', ')
When using rails you should take advantage of Active Record Associations.
I guess that a user(?) can choose different options from that second table.
The association would be a has_and_belongs_to_many-relation.
A good read is this section in the rails guide: http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
Basically you set up a join table between users and options and tell the two models that they have a has_and_belongs_to_many-relation with each other.
Then when you fetch a user you can simple call user.options and it shows the options that are related to that user object.

Rails Migration Column Type Polymorphic

I've got a little situation that I'd like to take care of, but I don't even know if it's possible.
In my app, I have one model that can take a parameter value, this parameter can be either a string or an integer or a boolean.
Instead of doing two string column (in my migration) with one labeled as "type" (the type - really !) and the other labeled as "value" (for the... value ! Yes !) i was wondering if it was possible that there is only the column value remaining, with polymorphics types in there.
The Model represent a property on a taks. Theses properties can be : is this task's open (type "boolean" and value "true" for exemple) ? Does this task has a percentage (type "integer", value "20") ? Note that the table also have a column name.
Polymorphism in Rails is more about associations where the class of the related item is unknown - not database columns with a dynamic type.
While is possible to implement a dynamic column in a relational database using two string columns value and value_type and use a custom getter to typecast value its going to get really messy. Another possibility is to use a something like a HSTORE or JSON column type but again do you really need it? Is there a better way to structure your business logic than trying to jam everything into a single column?
I'm guessing that what you may be looking for is something like an enum to denote the state of your model.
class Ticket < ActiveRecord::Base
enum status: [ :open, :closed, :pending, :active ]
end
This would use an integer column named status.
If you wanted to store additional information it would be prudent to use an additional database column. Like if you want to monitor the progress you would create an integer database column named tickets.progress.
For your answer, yes it is possible, but don't do it that way.
It is possible to use string for all different cases:
"integer:100", "integer:23", etc.
"boolean:true", "boolean:false", etc.
you will need to identify each data type(use concat)and convert to a right type and only then you can use the value.
But it is completely wrong and its implementation is going to be very complicated. I strongly recommend not to use this example or something similar.
I think that this is a wrong database structure.
In general, if you have a case in which you have a column that you think can contain more than one data type - something is wrong in your database and you should make a 'redesign' of your database.
Usually the best practice is to separate to different columns. In your case, your column can get different types, each type represents different information. I think your table should have these columns:
status_id - will reference to another table, Status that will contain all possible statuses(if there are more than 2 options).
progress/percentage - integer.
My answer isn't relevant for relational databases.

converting a string attribute to an array of strings

I am working on a model in rails, which has a column type that can have more than one values. In other words, as the users enter data in its database, new values might also be entered for that column. So it is like a one-to-many association. However, since the number of values will be very few (maybe less than 10), I did not want to create a separate model for it. By mistake, I had defined it as a string, but now I want to make it an array of strings, which can grow. How can I do that?
Thanks in advance!
What you're looking for is the serialize method.
Simply call serialize :attribute_name, Array in your model.

Rails 4 order by virtual attribute

I have a Product model which has name and description columns in the database.
I also have a Product.search_results_for(query), where query is a string like "Green Apple".
I need to return an ActiveRecord::Relation of the results ordered by which is the best hit. Currently, I'm setting a search_result_value to each product. search_result_value IS NOT a column in the database, and I don't want it to be.
So in essence, I have an ActiveRecord::Relation of Products that I need to order by search_result_value without changing it to an array, which is an instance variable that isn't stored in the database. How can I do this?
Something like this:
Product.order(:search_result_value)
If you do not put the value in a column or express the logic in search_result_value in pure SQL, then you’ll have to load all Products into memory and then sort them in Ruby using sort_by:
Product.all.to_a.sort_by(&:search_result_value)

efficiently storing "answers"

I'm building out an Answer ActiveRecord class that can have different types of answers. That is, the answer could be an integer, float, date, string... whatever...
The way I see it there are two ways to store the answers
1)
Have an attribute named "value" that is serialized.
This is nice since you can always access the answer from the same place. It probably sucks for searching answers since the data has to be de-serialized in order to be used (is this a correct assumption?)
2)
have several attributes integerValue, floatValue, etc...
This is easiest to search (if you know what type you're searching (which you probably do))
This sucks since the value isn't in the same place and need some hokey method like:
def value
stringValue||floatValue||integerValue
end
and some validations to ensure that only the correct one is set
What would you do??
I'd do one of two things:
Use single-table inheritance. Your table does contain those integerValue, floatValue, etc. fields; but it also contains a "type" field, and you'll subclass the Answer model to make IntegerAnswer, FloatAnswer, StringAnswer, etc. And then you can simply map the value accessor to one of those fields in each subclass. Look in the Agile book or Google on single-table inheritance in Rails for more on how to implement this.
Use a non-relational database. Something like MongoDB or CouchDB would render this problem moot; you could make value anything you wanted, or have multiple values per answer, or skip it entirely. I personally like Mongo with the MongoMapper gem, and if I had to address your use case that's the direction I'd go. It is getting away from ActiveRecord and "mainstream" Rails though, so you'd have to be comfortable with living at least a little on the edge.
What converting the value to a string in the database.
And using single table inheritance to define the type and retrieve the appropriate value.
You'd have one model Answer with two fields : one "value", which is a string.
And one "type", which is a string too and gets the type of the value.
Then for the float, you' have the following :
class FloatAnswer < Answer
def value
attributes['value'].to_f
end
end
When you do a Answer.find(:all), if the element has FloatAnswer as value, you will have a FloatAnswer object. Not an Answer one.
So you keep only one database field and always have the datas in the appropriate format.

Resources