how to specify two conditions in a collect in rails 4 - ruby-on-rails

In my system I have the notion of a cost. A cost belongs to one user and to one trip.
I am trying to extract all the costs that belong to a specific user and to a specific trip.
doing
#trip.costs.collect {|cost| [cost.value, cost.exchange_id]}
will get me all the costs for a specific trip
and doing
current_user.costs.collect {|cost| [cost.value, cost.exchange_id]}
will get me all the costs for a specific user.
How do I combine both of them?

collecting costs attributes for a specific trip of a specific user:
current_user.costs.where(trip_id: #trip.id).collect { |c| [c.value, c.exchange_id] }

Related

Include vs Join

I have 3 models
User - has many debits and has many credits
Debit - belongs to User
Credit - belongs to User
Debit and credit are very similar. The fields are basically the same.
I'm trying to run a query on my models to return all fields from debit and credit where user is current_user
User.left_outer_joins(:debits, :credits).where("users.id = ?", #user.id)
As expected returned all fields from User as many times as there were records in credits and debits.
User.includes(:credits, :debits).order(created_at: :asc).where("users.id = ?", #user.id)
It ran 3 queries and I thought it should be done in one.
The second part of this question is. How I could I add the record type into the query?
as in records from credits would have an extra field to show credits and same for debits
I have looked into ActiveRecordUnion gem but I did not see how it would solve the problem here
includes can't magically retrieve everything you want it to in one query; it will run one query per model (typically) that you need to hit. Instead, it eliminates future unnecessary queries. Take the following examples:
Bad
users = User.first(5)
users.each do |user|
p user.debits.first
end
There will be 6 queries in total here, one to User retrieving all the users, then one for each .debits call in the loop.
Good!
users = User.includes(:debits).first(5)
users.each do |user|
p user.debits.first
end
You'll only make two queries here: one for the users and one for their associated debits. This is how includes speeds up your application, by eagerly loading things you know you'll need.
As for your comment, yes it seems to make sense to combine them into one table. Depending on your situation, I'd recommend looking into Single Table Inheritance (STI). If you don't go this route, be careful with adding a column called type, Rails won't like that!
First of all, in the first query, by calling the query on User class you are asking for records of type User and if you do not want user objects you are performing an extra join which could be costly. (COULD BE not will be)
If you want credit and debit records simply call queries on Credit and Debit models. If you load user object somewhere prior to this point, use includes preload eager_load to do load linked credit and debit record all at once.
There is two way of pre-loading records in Rails. In the first, Rails performs single query of each type of record and the second one Rails perform only a one query and load objects of different types using the data returned.
includes is a smart pre-loader that performs either one of the ways depending on which one it thinks would be faster.
If you want to force Rails to use one query no matter what, eager_load is what you are looking for.
Please read all about includes, eager_load and preload in the article here.

Is there any way to perform recommendation for entities with one to many association?

I'm trying out recommendation system(academic exercise) for a specific use case where users and items are one to many associated. Say at a given time a particular item can be owned by only one user. User can own multiple items at a time. Any particular item has many similar items which might interest the owning user. I want to find an item and recommend it to user. Usually in user based recommendation, entities will be of many to many association. If user U1 owns items I1,I2,I3 and user U2 owns items I1,I2,I3,I4 we would recommend I4 to U1. In my case one item can be owned by only one user at a given time. How to perform recommendation in this case. Is it possible to perform user based recommendation?
One possible option is always to conert one problem to another. Given one-to-many information, you can for each item X (knowing some kind of similarity measure, which is required here, without it you cannot do any recomendation) you create an object "items similar to X to some extent" call it C[X], and once you go through all items -- you get new kind of data. You have users, and "items clusters" C. Now you can assume that user A "likes" cluster C[X] iff user A likes any item from C[X]. This way you have many-to-many relation on the same data, with a bit of "smoothing". Now you can use any kind of existing system, and once you get the recommendation C[Y] you "recommend" any free (avaliable) item from C[Y].

Splitting up EDI orders

We are implementing edi order processing and are currently about to check how we set up the interface.
Usually a order may carry multiple positions. For our customer it seems that an incoming order may need to be split up in multiple orders if they will be manufactured in different factories due to erp system requirements.
For me its sounds confusing if a customer does one order and gets back 3 different order numbers. One solution could be one position per order policy, however this increases the number of orders even when not needed.
The customer is sending an "ORDERS" message and will receive an order confirmation "ORDRSP".
I'm wondering whats the common solution to solve this problem? Manually keeping track of the sub orders thems to be no option has they are confirmed at different times, etc..
different solutions:
You split up orders: retailer will receive different shipments, different ASN's, etc (all referring to the same RetailersOrderNumber). But...not all retailers want this/can handle this.
Retailer splits up the orders (in most cases this means you will be 3 different manufacturers in their system ;-)
Factories deliver to one (manufacturers) DC where all the order/shipment handling is done.
(AFAIK these are the possibilities....)
kind regards, henk-jan

How to use ActiveRecord calculations with relations

I am trying to make an admin dashboard that shows an administrator relevant statistics about the site. For example, given a company has many users, finding the average number of users per company, or the maximum number of users a company has.
I have found activerecord::calculations, which seems to do most of what I want, but as far as I can tell, it doesn't let you do anything with relations. How would I go about finding counts or averages that are grouped by relations?
You have to think of it in terms of the User.
The simplest way would be
# get a hash of company_ids and user counts
User.group(:company_id).count
But then you'll have to load the Companies and match them up.
Then you could try and do
user_counts = User.group(:company_id).count
company_users = Company.all.map{|company| user_counts[company.id]}
# the maximum
company_users.max
# the average
company_users.sum.to_f / company_users.length

Performance issues with complex nested RoR reservation system

I'm designing a Ruby on Rails reservation system for our small tour agency. It needs to accommodate a number of things, and the table structure is becoming quite complex.
Has anyone encountered a similar problem before? What sort of issues might I come up against? And are performance/ validation likely to become issues?
In simple terms, I have a customer table, and a reservations table. When a customer contacts us with an enquiry, a reservation is set up, and related information added (e.g., paid/ invoiced, transport required, hotel required, etc).
So far so good, but this is where is gets complex. Under each reservation, a customer can book different packages (e.g. day trip, long tour, training course). These are sufficiently different, require specific information, and are limited in number, such that I feel they should each have a different model.
Also, a customer may have several people in his party. This would result in links between the customer table and the reservation table, as well as between the customer table and the package tables.
So, if customer A were to make a booking for a long trip for customers A,B and C, and a training course for customer B, it would look something like this.
CUSTOMERS TABLE
CustomerA
CustomerB
CustomerC
CustomerD
CustomerE
etc
RESERVATIONS TABLE
1. CustomerA
LONG TRIP BOOKINGS
CustomerA - Reservation_ID 1
CustomerB - Reservation_ID 1
CustomerC - Reservation_ID 1
TRAINING COURSE BOOKINGS
CustomerB - Reservation_ID 1
This is a very simplified example, and omits some detail. For example, there would be a model containing details of training courses, a model containing details of long trips, a model containing long trip schedules, etc. But this detail shouldn't affect my question.
What I'd like to know is:
1) are there any issues I should be aware of in linking the customer table to the reservations model, as well as to bookings models nested under reservations.
2) is this the best approach if I need to handle information about the reservation itself (including invoicing), as well as about the specific package bookings.
On the one hand this approach seems to be complex, but on the other, simplifying everything into a single package model does not appear to provide enough flexibility.
Please let me know if I haven't explained this issue very clearly, I'm happy to provide more information. Grateful for any ideas, suggestions or comments that would help me think through this rather complex database design.
Many thanks!
I have built a large reservation system for travel operators and wholesalers, and I can tell you that it isn't easy. There seems to be similarity yet still large differences in the kinds of product booked. Also, date-sensitivity is a large difference from other systems.
1) In respect to 'customers' I have typically used different models for representing different concepts. You really have:
a. Person / Company paying for the booking
b. Contact person for emergencies
c. People travelling
a & b seem like the same, but if you have an agent booking, then you might want to separate them.
I typically use a => 'customer' table, then some simple contact-fields for b, and finally for c use a 'passengers' table. These could be setup as different associations to the same model, but I think they are different enough, and I tend to separate them - perhaps use a common address/contact model.
2) I think this is fine, but depends on your needs. If you are building up itineraries for a traveller, then it makes sense to setup 'passengers' on the 'reservation', then for individual itinerary items, with links to which passenger is travelling on/using that item.
This is more complicated, and you must be careful to track dependencies, but the alternative is to not track passenger names, and simply assign quantities to each item (1xAdult, 2xChildren). This later method is great for small bookings, so it seems to depend on if your bookings are simple, or typically built up of longer itineraries.
other) In addition, in respect to different models for different product types, this can work well. However, there tends to be a lot of cross over, so some kind of common 'resource' model might be better -- or some other means of capturing common behaviour.
If I haven't answered your questions, please do ask more specific database design questions, or I can add more detail about specific examples of what I've found works well.
Good luck with the design!

Resources