I have a rails 4 application that has a form with many dollar input fields (all inside the same model).
I've made all of the fields decimals with precision => 10 and scale => 2. The issue I'm having is the input fields are masked with commas separating every '000'. I need to parse the commas out of all of these inputs before validating and saving to the database.
I need to store the value in the database as '150,000.00' so an external service can read the dollar value.
# Params
Parameters: {"requested_amount"=>"150,000.00"}
# SQL Update
SQL (0.7ms) UPDATE "requested_amount", "150.0"
With my current configuration, the database only saves what comes before the comma. I need to remove the comma so the SQL update can pass through the proper value.
Is there a gem that can do something like this? I've read into the rails-money gem and it seems a bit overkill for what I'm trying to accomplish.
Thanks
You want to use the money gem.
I just got done writing a financial application and it's the way to go.
There is some info missing.
What are you using to create the form?
Do you have verified if the value in the database is storing with commas?
Look at simple form gem to generate the form
If you think the money-rails gem is overkill, here's one approach:
Use integer column type to store money amount as cents, so 15000000 is stored.
Have a getter method to return a formatted value of the column, i.e. '150,000.00'
Related
We have a number of Meters which read a number of Parameters at a given interval and uploads the data (in CSV format) to a MYSQL database.
I have modelled this in Rails as follows:
Meter
has_many :parameters
Parameter
belongs_to :meter
has_many :readings
Reading
belongs_to :parameter
(I've used normal foreign keys - meter_id and parameter_id - to link the tables)
This is working great with my seed data and I'm using self.readings.pluck(:value).latest in my Parameter model in order to grab the latest value and pass it to the view.
The only problem is that the meters upload the data every 30 seconds. This means that - as there are currently 20 parameters - just over a months worth of data has left me with over 20,000,000 rows in my Readings table and this means that the queries to grab the latest are taking around 500ms each.
I'm after suggestions of ways to optimise this. I've added an index to the parameter_id field but, other than that, I'm not really sure of the best way to proceed...
It may be that I need to rethink the way that my database is structured, but this seemed to make most sense as I want to be able to dynamically add new parameters down the line (hence why I couldn't just make my columns the parameter names) and this seems to be the way that Rails stores data by default.
Thanks in advance.
If you are using Rails 3 and want to keep using a relational database your best option is to use table partitioning.
If you use PostgreSQL you can use the partitioned gem and check this slides to get an overview.
If you want to use Rails 4, since the partitioned gem is not compatible with ActiveRecord 4, I would advise you to use manual partitioning, you can use the year as your partition point, for example.
Check this blog post on Sharding and Partitioning and evaluate what should work best.
I've recently started looking into Ruby on Rails, and I've set up a basic system to scan an parse and XML datasource, storing the elements in a MySQL database.
I'm intending to run the script as a rake task at set intervals, so want to track additions and updates, outputting the new, or changed, values to a text file.
I initially looked at using the before_save in order to write self.changes to a file, however the complexity arises as I'm retrieving data from two different pages and want to group the log output, e.g note each pricing row is a different record in the same table, ignore the variable names these are examples.
Item GUID
- Price US: #{old price} to #{new price}
- Price UK: #{old price} to #{new price}
The solution I'm currently looking to implement is appending a logged column to the table, if the data changes I can set this to changed, or new if the record has been added, and use this in a query to find records in which logged is not NULL, and group them by GUID. However as this will execute after the object has been saved I lose knowledge of the past values.
Is there a different approach I could take to achieve something like this?
Yes, there is a better way to do this. Take a look at these options you've got:
audited gem: https://github.com/collectiveidea/audited
paper_trail gem: https://github.com/airblade/paper_trail
espinita gem: https://github.com/continuum/espinita
I'm using Rails 3.2 and MariaDB. I have this group of data:
description, services, facilities
Not indexed and purely for output in the show page. Should I store these as one JSON object in one more_info attribute or store as separate attributes?
I personally would make columns for them, it would generally make the fields easier to work with, especially if there will be need a to update the values. I usually reserve JSON serialized fields when I do not know how many attributes there will be.
If you are showing the data to your users I would recommend saving them in different columns. I find that as soon as users see something they want to filter by it or work with it in ways you have not foreseen.
If you are not then the choice is less clear cut but the very fact you have 3 distinct groups suggest that they are different things which could be treated differently as your application matures.
I would always go with the Normalised form unless you have documented reasons not to.
How do I save multiple values in a single cell record in Ruby on Rails applications?
If I have a table named Exp with columns named: Education, Experience, and Skill, what is the best practice if I want users to store multiple values such as: education institutions or skills in a single row?
I'd like to have users use multiple text fields, but should go into same cell record.
For instance if user has multiple skills, those skills should be in one cell? Would this be best or would it be better if I created a new table for just skills?
Please advise,
Thanks
I would not recommend storing multiple values in the same database column. It would make querying very difficult. For example, if you wanted to look for all the users with a particular skill set, the query would clumsy both on readability and performance.
However, there are still certain cases where it makes sense.
When you want to allow for variable list of data points
You are not going to query the data based on one of the values in the list
ActiveRecord has built-in support for this. You can store Hash or Array in a database column.
Just mark the columns as Text
rails g model Exp experience:text education:text skill:text
Next, serialize the columns in your Model code
class Exp < ActiveRecord::Base
serialize :experience, :education, :skill
# other model code
end
Now, you can just save the Hash or Array in the database field!
Exp.new(:skill => ['Cooking', 'Singing', 'Dancing'])
You can do it using a serialized list in a single column (comma-separated), but a really bad idea, read these answers for reasoning:
Is storing a delimited list in a database column really that bad?
How to store a list in a column of a database table
I suggest changing your schema to have a one to many relationship between users and skills.
Rails 4 and PostgreSQL comes with hstore support out of the box, more info here In rails 3 you can use gem to enable it.
It depends on what kind of functionality you want. If you want to bind the Exp model attributes with a form (for new and update operations) and put some validations on them, it is always better to keep it in a separate table. On the other hand, if these are just attributes, which you just need in database keep them in a single column. There is way by which you can keep the serialized object like arrays and hashes in database columns. Make them a array/hash as per your need and save it like this.
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize
Serialized attributes, automatically deserializes when they are pulled out of tables and serialized automatically when saved.
Where is the best place to define, and how should I store select/radio options for rails (and where to put translations)?
Right now I am defining a Hash within the model and storing the integer keys in the record. I've also placed the translations as 'attributes' within the model translations as it seems to group them together well. ie
PHYSICAL_CONDITIONS = {
1 => "activerecord.attributes.building.condition_excellent",
2 => "activerecord.attributes.building.condition_good",
3 => "activerecord.attributes.building.condition_average_for_age",
4 => "activerecord.attributes.building.condition_fair",
5 => "activerecord.attributes.building.condition_poor"
}.freeze
Is there a better way to do this? I have dozens of fields with options and do not want to create separate tables for each either.
My solution is:
use varchar to store the answer ie 'excellent', 'good' from above. This is actual meaningful data I can see in raw form vs numeric values.
in my model have the options array. The order is maintained and if I re-order them numbers don't matter:
PHYSICAL_CONDITIONS = [
:excellent,
:good
]
under the active record model translation have an options group for each set of options. In the above case I call it :physical_condition_options.
have each translation as a subset of that ie excellent: "Excellent"
If I ever need to convert this to allow multiple selections (checkbox) on the model (happened a number of times), I just remove this subset and make it part of the model. Migration is simpler instead of having to translate numeric values.
have a helper translate those options when passing it to a field
localized_options(Building::PHYSICAL_CONDITIONS,
"activerecord.attributes.building.physical_condition_options.")
This seemed to be the best way to store the data and allow it to be easily translated.