Count total number of records in Rails join table - ruby-on-rails

I have two models, users and departments, and a join table users_departments to enable a has_and_belongs_to_many association between them. I am using PostgreSQL as the database.
# users table columns
id
name
# departments table columns
id
name
# users_departments table columns
user_id
department_id
What is the best way in Rails for counting the total number of records in the users_departments table? Preferably without creating a new model class.
Please note that I do not want to count the records for a specific user or department (user.departments.count / departments.users.count), but the total number records for the table, considering all users and departments.

The best way is to just create a model called UsersDepartment and do a nice and easy query on that.
count = UsersDepartment.count
You can query the table directly however with exec_query which gives you an ActiveRecord::Result object to play with.
result = ActiveRecord::Base.connection.exec_query('select count(*) as count from users_departments')
count = result[0]['count']

Related

How to delete all logs except last 100 for each user in single table?

I have a single logs table which contains entries for users. I want to (prune) delete all but the last 100 for each user. I'd like to do this in the most efficient way (one statement using ActiveRecord if possible).
I know I can use the following:
.order(created_at: :desc) to get the records sorted
.offset(100) to get all records except the ones I want to keep
.ids to pluck the record ids
select(:user_id).distinct to get a list of all users in the table
The table has id, user_id, created_at columns (and others not pertinent to this question).
Each user should have at least the last 100 log entries remaining the logs table.
Not really sure how to do this using ruby syntax with my Log model. If it can't be done efficiently using ruby then I'll resort to using the SQL equivalent.
Any help much appreciated.
In SQL, you could do this:
DELETE FROM logs
USING (SELECT id
FROM (SELECT id,
row_number()
OVER (PARTITION BY user_id
ORDER BY created_at DESC)
AS rownr
FROM logs
) AS a
WHERE rownr > 100
) AS b
WHERE logs.id = b.id;
If the table is large, this will be slow.

Regenerate ids of existing records

I have a Rails app with a custom algorithm for id generation for one table. Now I decided to use default incremental ids generated by Postgres as primary keys and move my custom values from id to another column like uid. And I want to regenerate values in id column for all records - as normal from 1 to n.
What is the best way to do this? I have about 1000 records. Records from other tables are associated with these records.
You can keep whatever value is in ID column but create a new column named UID and set it as a primary key and auto increment
def self.up
execute "ALTER TABLE mytable modify COLUMN uid int(8) AUTO_INCREMENT"
end
You can tell your model to use UID as primary key as
self.primary_key = 'uid'
You can simply do it by iterating on your records, and updating them (and their associated objects). 1000 records is not that much to process.
Let's say that you have a table named "my_objects", with its model named "MyObject". Let's also say that you have another table, named "related_objects" and its model "RelatedObject"
You can iterate on all your MyObjects records, and update their related objects and the record itself at the same time.
records = MyObject.all #Whatever "MyObject" you have.
i = 0
records.each do |record|
#Updating whatever associated objects the record have
record.related_objects.each do |related_object|
related_object.update_column("my_object_id", i)
end
#Updating the record itself
record.update_column("id", i)
i++
end

Clean and concise way to find active records that have the same id as another set of active records

I have a table called shoppers and another table called Users. I have a shopper_id which is the foreign key in the Shoppers table and refers to the primary key id in the Users table.
I ran a query called #shoppers = shoppers.where("some condition")
This allowed me to get a set of shoppers who satisfy the condition. Next I would like to select those Users who have the same id as the shopper_id as the individual objects in #shoppers.
I know I could do this by writing a loop, but I am wondering if ruby on rails allows me to write a Users.where condition that can help me obtain the subset of user objects with the same id as shopper_id arranged in ascending order by the name field in the Users table.
Any ideas?
Try this.
#shoppers = Shopper.where("some condition")
#users = User.where(id: #shoppers.collect(&:shopper_id)).order('name asc')

Compare 3 tables in SQLite

Originally, I have 2 tables. I normalized it since the relationship of this tables is many to many. Now I have 3.
Jobs
jID PK
jName
jDesc
jEarnings
jTags
Course
cID PK
cName
cDesc
cSchool
cProgram
JobsCourse
ID PK
jID FK
cID FK
My app displays a tableview of the jobs
When clicked it displays the UIViewcontroller of jobs plus a tableview of the related course
How do I query the jobcourse table so that I can get all the related Courses to a certain job?
You can join the two tables, e.g.:
SELECT course.* FROM course INNER JOIN jobscourse ON jobscourse.cID = course.cID WHERE jobscourse.jID = ?
That gets all entries from course where the jID in jobscourse is equal to some value.

Rails 3 Select Distinct Order By Number of Occurrences

In one of my models I have a country column. How would I go about selecting the top 3 countries based on how many models have that country?
Without any further information you can try this out:
YourModel.group('country').order('count_country DESC').limit(3).count('country')
when you call count on a field rails automatically adds an AS count_field_name field to your query.
Count must be called at the end of the query because it returns an ordered hash.

Resources