RAILS HOW TO CALCULATE TOTAL VALUE WITH FIELDS IN DIFFERENT TABLES - ruby-on-rails

Good night people. I'm new to rails and I'm using translate to post in English.
a question.
I have three tables: "ride_request_objects", "ata_objects" and "ride_requests".
They are related:
Model: ride_requests
has_many :ride_request_objects
has_many :ata_objects, through: :ride_request_objects
Model: ride_request_objects
belongs_to :ata_object
Model: ata_objects
has_many :ride_request_objects
has_many :ride_requests, through: :ride_request_objects
I need to calculate the "total" in "ride_request_objects", which would be:
ride_request_objects.quantity * ata_objects.unit_value
imagem da tabela:
https://i.stack.imgur.com/uWv1g.png
How can I do this iteration for the calculation? would it be inside the Model of "ride_request_objects"?

I'm assuming you want the total for each RideRequest object (ie. not a single total for all records). If so then you can use a neat, almost hidden feature of ActiveRecord, where you can add arbitrary extra fields to a select and AR will automatically make them available as getters on the resulting objects, eg.
rrs = RideRequest.joins(:ata_objects).references(:ride_request_objects, :ata_objects).select( "ride_requests.*, SUM(ata_objects.unit_value * ride_request_objects.quantity) AS ata_sum").group(:id)
rrs.first.ata_sum

Related

How to increase performance using association in rails

Hi can anyone tell me how can i increase performance if association returns large no. of records. for example in my app :-
class Restaurant < ActiveRecord::Base
has_many :inventory_items
end
class InventoryItem < ActiveRecord::Base
belongs_to :vendor
end
i am trying to find the vendors of my restuarant as follow :-
current_restaurant.inventory_items.includes(:vendor).uniq
current_restaurant.inventory_items returns large no. of records which takes maximum time. so how can i reduce this time please help me.
There are a number of solutions that you can use depending on how your application is configured and what it needs to do -
Only select the columns that you want, for example, if you are only looking for the IDs, you can use the pluck or select methods.
As Chetan suggested in his answer, you can also add scopes, and in addition to that also add indexes for the columns in the scope depending on what kind of columns they are.
If you are looking at calculated values, consider caching them on the Restaurant table.
You can add a scope to your model and add a condition for the records you wanna fetch. Like
scope :your_scope_name, -> { includes(:vendor).where(*some more conditions*) }
This will help query to not to go through all data
Use pagination, loading all records is never recommended..
see will_paginate OR kaminari gems
Update:
class Restaurant < ActiveRecord::Base
has_many :inventory_items
has_many :vendors, through: :inventory_items
end
Then,
current_restaurant.vendors.uniq
It depends on the size of the tables and how they are indexed, one sub query might be faster than a huge join:
Vendor.where(id: current_restaurant.inventory_items.select(:vendor_id).distinct)

Should I use a LIKE query for these ActiveRecord relationships?

Let's say I have a single web page form user interface with 2 sets of checkboxes. With set 1 checkboxes, I can check off what Trainers I would like ("Jason", "Alexandra, etc.) With set 2 checkboxes, I can check off what animals I would like to see ("Tigers", "Bears", etc.) Once I submit the form with these options, I get back a list of zoos that match the criteria (let's assume all the trainers work at all the zoos and all the animals are at all the zoos for discussion's sake)
We'll be running our database query by "name" (e.g., search using trainer names and animal names, NOT database ids)
Let's say we are using a Postgres database that has hundreds of thousands of rows (if not millions).
Is it more efficient to search using an "ILIKE" query or is it better to do a standard join query (e.g., Zoo.includes(:animals, :trainers).where("animals.name = ? and trainers.name = ?", animal_names, trainer_names)?
Is there a better way than what I just showed in #1 above?
model setup
class Zoo < ActiveRecord::Base
has_many :animals, through: zoo_animals
has_many :trainers, through: zoo_trainers
has_many :zoo_trainers
has_many :zoo_animals
end
class Animal < ActiveRecord::Base
has_many :zoos, through :zoo_animals
has_many :zoo_animals
end
class Trainer < ActiveRecord::Base
has_many :zoos, through :zoo_trainers
has_many :zoo_trainers
end
class ZooAnimal < ActiveRecord::Base
belongs_to :animal
belongs_to :zoo
end
class ZooTrainer < ActiveRecord::Base
belongs_to :zoo
belongs_to :trainer
end
EDIT: let's suppose I don't have access to the database ID's.
LIKE '%Jason%' is much less efficient than querying for the exact string 'Jason' (or querying for an ID), because while exact comparisons and some uses of LIKE can use an index on the column being queried, LIKE with a pattern beginning with a wildcard can't use an index.
However, performance doesn't sound like the most important consideration here. LIKE %Jason% will still probably be fast enough on a reasonably sized database under reasonable load. If the application really needs to search for things by substring (which implies that a search might have multiple results), that requirement can't be met by simple equality.
There are an endless number of higher-powered solutions to searching text, including Postgres built-in full-text search and external solutions like Elasticsearch. Without specific requirements for scaling I'd go with LIKE until it started to slow down and only then invest in something more complicated.

Best way to program varying cost of child admissions in Ruby?

I'm writing a program in which visitors would select how many kids they have, then provide their ages. I would then need to calculate their total cost according to the kid's ages and cost for each age.
I assume I would need to serialize a hash in order to get this data into the ActiveRecord but I'm confused as to how I would read this hash and calculate it against the hash provided by the user.
Is serialize the way to go with this particular problem or is there a better way?
Postgresql does recognize Arrays as a data type. So you could go that route. Though, you might want to separate out this data into it's own table.
class User < ActiveRecord::Base
has_many :children
...
class Children < ActiveRecord::Base
belongs_to :user, dependent: :destroy
...
And table schema something like:
table: users
|id|fname|lname|...
table: children
|id|name|user_id|...
So now it doesn't matter how many children each user has, you will always have a simple interface for adding, deleting and querying them.
c = User.first
c.children #returns array of Child objects.
Serialize is certain a way to go, but a model and a table allows you to be much more DB agnostic.
I think, hash serialization is not quite a RoR way.
Instead, having ActiveRecord model for a cost by age
AgeCost
--------
age: int
cost: decimal
one can easily find a total cost
kids_ages = [4, 7, 10]
total_cost = 0
kids_ages.each do |kid_age|
age_cost = AgeCost.find_by_age(kid_age)
total_cost += age_cost.cost if age_cost
end

Ruby on Rails: Proper Syntax for 2 dimensional Array in Database

I plan to insert a two-dimensional array into the database with ActiveRecord.
The reason why: I want users to select multiple languages and the corresponding language-levels (like how good they speak it). I do not want to have two fields for both languages & language_levels, I want those two to be hooked together from the beginning. Sure, I could hook them together later on the model level, but I want to try it the other way first.
Example:
[ ["English",2], ["German",1], ["Japanese",1] ]
I've been able to store one-dimensional arrays, though had no luck with these. Trying to make those accessible using something like (languages: [][]) in the strong parameters didn't work.
Thanks
I understand your intent to do this with sort of minimal effort, but you should definitely consider looking into storing things the normalized way.
The intention is – what to do with lang. skills for all your users, once there's a need to rename a language? Say you had Chinese language as of the start, but then you've decided to keep two of them, Chinese (traditional) and Chinese (simplified). You'd now have to write an error-prone update script.
In case of keeping the languages normalized way, I'd keep three models for consistency:
class User < ActiveRecord::Base
has_many :language_skills
has_many :languages, through: :language_skills
end
class Language < ActiveRecord::Base
has_many :language_skills
has_many :users, through: :language_skills
end
class LanguageSkill < ActiveRecord::Base
belongs_to :user
belongs_to :language
end
I would definitely go for something like
User
has_many languages_skills
LanguageSkill
belongs_to User
language: string
level: integer
Then use nested forms to add everything together
I would NOT use multi-dimensional arrays

Pricelist how to store in database?

I need to store a pricelist in the database.
What is the best way to store a pricelist?
Example of the pricelist:
I have thinked of 2 solutions.
Create a table named products, with the columns:
name (varchar)
price (integer)
price_2 (integer)
The name would then be example for example be "product_a1" used to refer to the YAML translation file.
And then create all the name of the products. So example in my case there would be about 100.
Solution 2:
Store all the data in one row. So the table columns would be:
product_a1
product_a2
product_a3
product_b1
product_b1_2
product_b2
product_b2_2
and 99 more..
PS: I have only 1 pricelist
Why don't you use the Entity–attribute–value model (EAV), this way you can get as many attributes on your model as you want. It gives you great flexibility, so in the future you can add more attributes dynamically without refactoring your code.
Why not create two tables with a relationship between them:
class Product < ActiveRecord::Base
has_many :prices
end
and
class Price < ActiveRecord::Base
belongs_to: :product
end
This gives you the flexibility to add additional prices in the future if necessary. I'm loath to hardcode databases with fixed limits.

Resources