Can the sortable_table plugin do order by multiple columns? - ruby-on-rails

I'm using the sortable_table plugin for sorting an HTML table in a Rails app.
If we want to order by multiple columns, can sortable_table plugin do it
?
Example:
select distinct brands.title as brands, models.title as model
from brands, models
where
brands.id = models.brand_id
order by brands.title desc, models.title desc

Oh.. I get it!
Just put sortable_attributes on controller as array.
For example:
sortable_attributes :brand_model => ["brands.title", "models.title"]

Related

RoR PostgresQL - Get latest, distinct values from database

I am trying to query my PostgreSQL database to get the latest (by created_at) and distinct (by user_id) Activity objects, where each user has multiple activities in the database. The activity object is structured as such:
Activity(id, user_id, created_at, ...)
I first tried to get the below query to work:
Activity.order('created_at DESC').select('DISTINCT ON (activities.user_id) activities.*')
however, kept getting the below error:
ActiveRecord::StatementInvalid: PG::InvalidColumnReference: ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
According to this post: PG::Error: SELECT DISTINCT, ORDER BY expressions must appear in select list, it looks like The ORDER BY clause can only be applied after the DISTINCT has been applied. This does not help me, as I want to get the distinct activities by user_id, but also want the activities to be the most recently created activities. Thus, I need the activities to be sorted before getting the distinct activities.
I have come up with a solution that works, but first grouping the activities by user id, and then ordering the activities within the groups by created_at. However, this takes two queries to do.
I was wondering if what I want is possible in just one query?
This should work, try the following
Solution 1
Activity.select('DISTINCT ON (activities.user_id) activities.*').order('created_at DESC')
Solution 2
If not work Solution 1 then this is helpful if you create a scope for this
activity model
scope :latest, -> {
select("distinct on(user_id) activities.user_id,
activities.*").
order("user_id, created_at desc")
}
Now you can call this anywhere like below
Activity.latest
Hope it helps

Rails sub select query

I am trying to Sub Select using Rails ActiveRecord?
SELECT * FROM (
< sub query >
) as T
GROUP BY <COLUMN_NAME> ORDER BY <ANOTHER_COLUMN> DESC
I got the subquery part using ActiveRecord. However, I am trying to get the whole thing done using ActiveRecord.
I am not sure if there is a better way or not, but I ended up doing this for now.
How do you get a count of a subquery in Active Record?

PostgreSQL in Rails: sorting object by two date attributes in descending order

I have an index of active job positions. Currently, they're sorted by the most recent i.e. created_at. However, recently i've added in a renewal feature that updates a renewal_date attribute without updating the created_at.
What I want to achieve is to sort the list in descending order using both renewal_date and created_at.
jobs = Job.where(active: true).reorder("renewal_date DESC NULLS LAST", "created_at DESC")
With this code, the renewed job will always be at the top regardless of how many new jobs are created. How do I sort it so it checks for the date for both attributes and sorts it according to most recent?
Your code will order first by renewal_date with nulls at the end, and then will look at the created_at if two records have the same renewal_date.
I assume that what you want to do is something like "max(renewal_date, created_at)", which will take the "last modification date", or another custom way to compare the two fields.
If then, you can find your answer here : merge and order two columns in the same model
Job.where(active: true).reorder('GREATEST(renewal_date, created_at) DESC')
Let try a standard SQL, so it can work with all types of database:
Job.where(active: true).order('CASE WHEN renewal_date IS NULL THEN created_at ELSE renewal_date END DESC')

Rails - How to order query of sum() and group()?

In our Rails 4.2 app, here is query which does sum() and group() on payment record:
Payment.joins(:project, :pr_category).select("sum(payments.amount) as Total, projects.name as Project, definitions.name as Category").group('payments.project_id, payments.pr_category_id').order('payments.project_id')
The query does its job creating sum based on project and its category. However we are having hard time to order it by project_id (records for one project were scattered). We also tried order('Project') to no avail (we did not try to add a project_id as an column and try to order on it since we don't need the id). Also tried to put order right after joins. All these can not change the order of the query. What's the right way to order a query out of sum() and group()?
You can sort outside of ActiveRecord by using sort_by of the Enumerable mixins:
Payment.joins(:project, :pr_category).select("sum(payments.amount) as Total, projects.name as Project, definitions.name as Category, payments.project_id as project_id").group('payments.project_id, payments.pr_category_id').sort_by { |p| c.project_id }

Rails 3 Comparing foreign key to list of ids using activerecord

I have a relationship between two models, Registers and Competitions. I have a very complicated dynamic query that is being built and if the conditions are right I need to limit Registration records to only those where it's Competition parent meets a certain criteria. In order to do this without select from the Competition table I was thinking of something along the lines of...
Register.where("competition_id in ?", Competition.where("...").collect {|i| i.id})
Which produces this SQL:
SELECT "registers".* FROM "registers" WHERE (competition_id in 1,2,3,4...)
I don't think PostgreSQL liked the fact that the in parameters aren't surrounded by parenthesis. How can I compare the Register foreign key to a list of competition ids?
you can make it a bit shorter and skip the collect (this worked for me in 3.2.3).
Register.where(competition_id: Competition.where("..."))
this will result in the following sql:
SELECT "registers".* FROM "registers" WHERE "registers"."competition_id" IN (SELECT "competitions"."id" FROM "competitions" WHERE "...")
Try this instead:
competitions = Competition.where("...").collect {|i| i.id}
Register.where(:competition_id => competitions)

Resources