Rails 4 how to include polymorphic - ruby-on-rails

I have a Webcam model which has many Urls
class Webcam < ActiveRecord::Base
has_many :urls, -> { where('kind LIKE ?','preview_url')}, :as => :urlable, :dependent => :destroy
has_one :preview_url, -> { where('kind LIKE ?', 'preview_url') }, :as => :urlable, :dependent => :destroy, :class_name => 'Url'
end
class Url < ActiveRecord::Base
belongs_to :urlable, polymorphic: true
end
So Webcam.joins(:preview_url).where(:id=>cam_ids) does work, but I still have a sql call for each cam.
Url Load (0.2ms) SELECT "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3 ORDER BY "urls"."id" ASC LIMIT 1 [["urlable_id", 9756], ["urlable_type", "Webcam"], ["kind", "preview_url"]]
CACHE (0.0ms) SELECT "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3 ORDER BY "urls"."id" ASC LIMIT 1 [["urlable_id", 9756], ["urlable_type", "Webcam"], ["kind", :preview_url]]
Url Load (0.2ms) SELECT "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3 ORDER BY "urls"."id" ASC LIMIT 1 [["urlable_id", 9759], ["urlable_type", "Webcam"], ["kind", "preview_url"]]
CACHE (0.0ms) SELECT "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3 ORDER BY "urls"."id" ASC LIMIT 1 [["urlable_id", 9759], ["urlable_type", "Webcam"], ["kind", :preview_url]]
Url Load (0.2ms) SELECT "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3 ORDER BY "urls"."id" ASC LIMIT 1 [["urlable_id", 9760], ["urlable_type", "Webcam"], ["kind", "preview_url"]]
CACHE (0.0ms) SELECT "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3 ORDER BY "urls"."id" ASC LIMIT 1 [["urlable_id", 9760], ["urlable_type", "Webcam"], ["kind", :preview_url]]
How can I avoid these many sql calls?

You should use .includes(:urls, :preview_url) (not .joins) to avoid N+1 queries problem (see Rails Guides on the topic).
You should also have a separate urls.kind value for preview_url because you can't distinguish it from other urls now.

Related

Webrick or Puma, random 500 errors with no log. Is there a better log

my app is crashing randomly in development.
I start using Puma, sometimes on page request it crash.
No log, only a generic error 500.
Now I switch to Webrick, the same.
CACHE Product Load (0.0ms) SELECT "products".* FROM "products" INNER JOIN "product_relations" ON "products"."id" = "product_relations"."product_id" WHERE "product_relations"."productable_id" = $1 AND "product_relations"."productable_type" = $2 AND "products"."state" = $3 AND "products"."published_at" <= '2020-05-04 20:52:34.630525' ORDER BY "products"."published_at" DESC LIMIT $4 [["productable_id", 34969], ["productable_type", "Content"], ["state", "active"], ["LIMIT", 11]]
CACHE Brand Load (0.0ms) SELECT "brands".* FROM "brands" INNER JOIN "content_brands" ON "brands"."id" = "content_brands"."brand_id" WHERE "content_brands"."content_id" = $1 ORDER BY "brands"."name" ASC LIMIT $2 [["content_id", 34969], ["LIMIT", 11]]
CACHE Product Load (0.0ms) SELECT "products".* FROM "products" INNER JOIN "product_relations" ON "products"."id" = "product_relations"."product_id" WHERE "product_relations"."productable_id" = $1 AND "product_relations"."productable_type" = $2 AND "products"."state" = $3 AND "products"."published_at" <= '2020-05-04 20:52:34.630525' ORDER BY "products"."published_at" DESC LIMIT $4 [["productable_id", 34969], ["productable_type", "Content"], ["state", "active"], ["LIMIT", 11]]
CACHE Brand Load (0.0ms) SELECT "brands".* FROM "brands" INNER JOIN "content_brands" ON "brands"."id" = "content_brands"."brand_id" WHERE "content_brands"."content_id" = $1 ORDER BY "brands"."name" ASC LIMIT $2 [["content_id", 34969], ["LIMIT", 11]]
Rendered app/cells/product_reviews/show.html.haml (Duration: 77.6ms | Allocations: 31933)
Rendered contents/review.html.haml within layouts/application (Duration: 184.7ms | Allocations: 109291)
Completed 500 Internal Server Error in 233ms (ActiveRecord: 23.7ms | Allocations: 140545)
I need to reboot the server, and then the page load.
No error, only a generic Completed 500 Internal Server Error
I have in my development.rb
config.consider_all_requests_local = true
and
config.log_level = :debug
Is there a deeper log???

terminal output for Rails app produces double requests

My Rails app generates double requests with every page load, and I'm not able to diagnose the source of the problem. Answers here suggest removing all blank/self-referencing hrefs and running rake assets:clean - but neither has any impact.
Both of these requests are identical, save for timestamps and the as part of the controller action processing. The first request says Processing by TradesController#index as HTML whereas the second says Processing by TradesController#index as */*
Has anyone else dealt with this, and if so, how did you fix it?
Started GET "/swaps" for 2600:1700:ba01:ff10:cc31:d814:a204:d70e at 2020-02-23 14:32:25 -0800
Processing by TradesController#index as HTML
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.4ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_requester_id" = $1 AND "trades"."approved_at" IS NULL [["trade_requester_id", 1]]
(0.3ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_recipient_id" = $1 AND "trades"."approved_at" IS NULL [["trade_recipient_id", 1]]
Rendering trades/index.html.erb within layouts/application
Rendered trades/_trades_menu.html.erb (0.5ms)
CACHE (0.0ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_recipient_id" = $1 AND "trades"."approved_at" IS NULL [["trade_recipient_id", 1]]
Rendered trades/index.html.erb within layouts/application (3.0ms)
CACHE (0.0ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_recipient_id" = $1 AND "trades"."approved_at" IS NULL [["trade_recipient_id", 1]]
Transaction Load (0.5ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."recipient_id" = $1 AND "transactions"."archived_by_recipient" = $2 [["recipient_id", 1], ["archived_by_recipient", false]]
Transaction Load (0.5ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."sender_id" = $1 AND (state = 'approved' OR state = 'force_flipped' OR state = 'payment_sent' OR state = 'payment_declined' OR state = 'passed' OR state = 'paid' OR state = 'refunded' OR state = 'shipped' OR state = 'received' OR state = 'not_received' OR state = 'unpaid' OR state = 'ignored' OR state = 'declined') AND "transactions"."archived_by_sender" = $2 [["sender_id", 1], ["archived_by_sender", false]]
PaymentTransfer Load (0.3ms) SELECT "payment_transfers".* FROM "payment_transfers" WHERE "payment_transfers"."user_id" = $1 AND (user_id = 1 AND read = FALSE) [["user_id", 1]]
CACHE Transaction Load (0.0ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."recipient_id" = $1 AND "transactions"."archived_by_recipient" = $2 [["recipient_id", 1], ["archived_by_recipient", false]]
CACHE Transaction Load (0.0ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."sender_id" = $1 AND (state = 'approved' OR state = 'force_flipped' OR state = 'payment_sent' OR state = 'payment_declined' OR state = 'passed' OR state = 'paid' OR state = 'refunded' OR state = 'shipped' OR state = 'received' OR state = 'not_received' OR state = 'unpaid' OR state = 'ignored' OR state = 'declined') AND "transactions"."archived_by_sender" = $2 [["sender_id", 1], ["archived_by_sender", false]]
CACHE PaymentTransfer Load (0.0ms) SELECT "payment_transfers".* FROM "payment_transfers" WHERE "payment_transfers"."user_id" = $1 AND (user_id = 1 AND read = FALSE) [["user_id", 1]]
(1.2ms) SELECT COUNT(*) FROM "conversations" INNER JOIN "messages" ON "messages"."conversation_id" = "conversations"."id" INNER JOIN "users" ON "users"."id" = "messages"."user_id" WHERE ((conversations.sender_id = 1 OR conversations.receiver_id = 1)) AND (messages.user_id != 1 AND read = FALSE)
Rendered layouts/_header.html.erb (9.2ms)
Completed 200 OK in 58ms (Views: 48.5ms | ActiveRecord: 4.2ms)
(0.2ms) BEGIN
(0.2ms) COMMIT
Started GET "/swaps" for 2600:1700:ba01:ff10:cc31:d814:a204:d70e at 2020-02-23 14:32:26 -0800
Processing by TradesController#index as */*
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.4ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_requester_id" = $1 AND "trades"."approved_at" IS NULL [["trade_requester_id", 1]]
(0.4ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_recipient_id" = $1 AND "trades"."approved_at" IS NULL [["trade_recipient_id", 1]]
Rendering trades/index.html.erb within layouts/application
Rendered trades/_trades_menu.html.erb (0.6ms)
CACHE (0.0ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_recipient_id" = $1 AND "trades"."approved_at" IS NULL [["trade_recipient_id", 1]]
Rendered trades/index.html.erb within layouts/application (27.1ms)
CACHE (0.0ms) SELECT COUNT(*) FROM "trades" WHERE "trades"."trade_recipient_id" = $1 AND "trades"."approved_at" IS NULL [["trade_recipient_id", 1]]
Transaction Load (0.5ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."recipient_id" = $1 AND "transactions"."archived_by_recipient" = $2 [["recipient_id", 1], ["archived_by_recipient", false]]
Transaction Load (0.6ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."sender_id" = $1 AND (state = 'approved' OR state = 'force_flipped' OR state = 'payment_sent' OR state = 'payment_declined' OR state = 'passed' OR state = 'paid' OR state = 'refunded' OR state = 'shipped' OR state = 'received' OR state = 'not_received' OR state = 'unpaid' OR state = 'ignored' OR state = 'declined') AND "transactions"."archived_by_sender" = $2 [["sender_id", 1], ["archived_by_sender", false]]
PaymentTransfer Load (0.3ms) SELECT "payment_transfers".* FROM "payment_transfers" WHERE "payment_transfers"."user_id" = $1 AND (user_id = 1 AND read = FALSE) [["user_id", 1]]
CACHE Transaction Load (0.0ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."recipient_id" = $1 AND "transactions"."archived_by_recipient" = $2 [["recipient_id", 1], ["archived_by_recipient", false]]
CACHE Transaction Load (0.0ms) SELECT "transactions".* FROM "transactions" WHERE "transactions"."sender_id" = $1 AND (state = 'approved' OR state = 'force_flipped' OR state = 'payment_sent' OR state = 'payment_declined' OR state = 'passed' OR state = 'paid' OR state = 'refunded' OR state = 'shipped' OR state = 'received' OR state = 'not_received' OR state = 'unpaid' OR state = 'ignored' OR state = 'declined') AND "transactions"."archived_by_sender" = $2 [["sender_id", 1], ["archived_by_sender", false]]
CACHE PaymentTransfer Load (0.0ms) SELECT "payment_transfers".* FROM "payment_transfers" WHERE "payment_transfers"."user_id" = $1 AND (user_id = 1 AND read = FALSE) [["user_id", 1]]
(0.7ms) SELECT COUNT(*) FROM "conversations" INNER JOIN "messages" ON "messages"."conversation_id" = "conversations"."id" INNER JOIN "users" ON "users"."id" = "messages"."user_id" WHERE ((conversations.sender_id = 1 OR conversations.receiver_id = 1)) AND (messages.user_id != 1 AND read = FALSE)
Rendered layouts/_header.html.erb (8.7ms)
Completed 200 OK in 152ms (Views: 116.6ms | ActiveRecord: 4.1ms)
(0.1ms) BEGIN
(0.1ms) COMMIT

How to fetch records from last 7 days with padding to 0 if no records found?

I'm trying to fetch records from the last 7 days (may change to support month and year) to populate a chart, and I need to pad the days where no records where found to 0. I first tried grouping but found no way of padding the data, so I came up with this:
today = Date.today
array_data = (today - 6.days..today).map do |day|
total_time = #project.time_entries.where(created_at: (day.beginning_of_day..day.end_of_day)).map(&:duration_hours).sum
{ day.strftime("%a %d %b") => total_time }
end
#entries_data = array_data.reduce Hash.new, :merge
The result is a hash with a day as a key and the sum of a calculated property as the value.
This however, requires a database query for each day:
TimeEntry Load (1.1ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" IN ('bd9f541c-e37a-45de-bc94-28bef2b5eade')
TimeEntry Load (0.4ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-21 04:30:00.000000' AND '2016-03-22 04:29:59.999999') [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
TimeEntry Load (0.2ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-22 04:30:00.000000' AND '2016-03-23 04:29:59.999999') [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
TimeEntry Load (0.2ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-23 04:30:00.000000' AND '2016-03-24 04:29:59.999999') [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
TimeEntry Load (0.2ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-24 04:30:00.000000' AND '2016-03-25 04:29:59.999999') [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
TimeEntry Load (0.5ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-25 04:30:00.000000' AND '2016-03-26 04:29:59.999999') [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
TimeEntry Load (0.6ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-26 04:30:00.000000' AND '2016-03-27 04:29:59.999999') [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
TimeEntry Load (0.5ms) SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-27 04:30:00.000000' AND '2016-03-28 04:29:59.999999') [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
How can I rework this to make it send only 1 query to the database?
Not certain this is what you mean, but here's what I think you need to do:
Run the query getting all data for the last N days.
Group these records by the day
Merge this on top of a hash with values of { date => 0} for each of the last N days
Ok, as tpbowden mentioned in his answer, I managed to reduce it to 1 query like this:
date_format = "%d %b"
entries_last_week = time_entries.group_by { |t| t.created_at.to_date.strftime(date_format) }.map { |k, v| { k => v.map(&:duration_hours).sum } }
entries_hash = entries_last_week.reduce Hash.new, :merge
today = Date.today
days = (today - 6.days..today).map { |day| { day.strftime(date_format) => 0 } }
hash_of_days = days.reduce Hash.new, :merge
hash_of_days.merge(entries_hash)

order active_admin column by parent item in belongs_to relationship

I have two models: show_request and show. A show_Request belongs_to a show and a show has_many show_requests. On the show_request page in active_admin, I want to order show_requests by the show's created_at value. Here is my code so far:
ActiveAdmin.register ShowRequest do
controller do
def scoped_collection
end_of_association_chain.includes(:show)
#I also tried ShowRequest.includes(:show)
end
end
index do
column 'Show', sortable: "shows.created_at_asc" do |show_req|
link_to show_req.show.name, admin_show_path(show_req.show)
end
end
end
Here are the server logs:
Started GET "/admin/show_requests" for 127.0.0.1 at 2015-09-18 09:35:36 -0400
Processing by Admin::ShowRequestsController#index as HTML
AdminUser Load (0.3ms) SELECT "admin_users".* FROM "admin_users" WHERE "admin_users"."id" = 1 ORDER BY "admin_users"."id" ASC LIMIT 1
(1.2ms) SELECT COUNT(*) FROM "show_requests" WHERE (not_going_to_show = 'f' OR i_want_my_horse_to_compete = 't')
(0.2ms) SELECT COUNT(*) FROM "show_requests"
(0.2ms) SELECT COUNT(*) FROM "show_requests" WHERE (not_going_to_show = 't' AND i_want_my_horse_to_compete = 'f')
(0.3ms) SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "show_requests" WHERE (not_going_to_show = 'f' OR i_want_my_horse_to_compete = 't') LIMIT 30 OFFSET 0) subquery_for_count
CACHE (0.0ms) SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "show_requests" WHERE (not_going_to_show = 'f' OR i_want_my_horse_to_compete = 't') LIMIT 30 OFFSET 0) subquery_for_count
CACHE (0.0ms) SELECT COUNT(*) FROM "show_requests" WHERE (not_going_to_show = 'f' OR i_want_my_horse_to_compete = 't')
CACHE (0.0ms) SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "show_requests" WHERE (not_going_to_show = 'f' OR i_want_my_horse_to_compete = 't') LIMIT 30 OFFSET 0) subquery_for_count
ShowRequest Load (2.0ms) SELECT "show_requests".* FROM "show_requests" WHERE (not_going_to_show = 'f' OR i_want_my_horse_to_compete = 't') ORDER BY "show_requests"."id" desc LIMIT 30 OFFSET 0
Show Load (9.7ms) SELECT "shows".* FROM "shows" WHERE "shows"."id" IN (2, 1)
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 2]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
Show Load (0.2ms) SELECT "shows".* FROM "shows"
User Load (0.2ms) SELECT "users".* FROM "users"
This is not working. It is not affecting the order of the columns at all. How do I fix this?
Take a look at this part of the log:
ShowRequest Load (2.0ms) SELECT "show_requests".* FROM "show_requests" WHERE (not_going_to_show = 'f' OR i_want_my_horse_to_compete = 't') ORDER BY "show_requests"."id" desc LIMIT 30 OFFSET 0
Show Load (9.7ms) SELECT "shows".* FROM "shows" WHERE "shows"."id" IN (2, 1)
You can see that the ShowRequests and Shows are loaded in separate queries. sortable is not going to work here, because you can't order one table by a field of another without a join. The fix should be to tell ActiveRecord that you need to reference the shows table in your query:
controller do
def scoped_collection
super.includes(:show).references(:shows)
end
end
index do
column :show, sortable: 'shows.created_at'
end
references only works with includes, and forces Rails to perform a join when eager loading.

active record quering in rails 4 and postgres

I have 2 models
Class Ride
has_many :trips
#state (string: active or expired)
end
Class Trip
#date (Date attribute)
scope :active, -> (start_at = Date.today) { where("trips.date >= ?", [Date.today, start_at].max) }
end
Daily, I need update state on Rides with active state having all trips with date attribute < Date.today
how to perform this in 1 query?
i can archive such result using:
Ride.with_active_state.select{|r| r.trips.active.size ==0}
but it makes huje queries to count trips, eq:
[1] pry(main)> Ride.with_active_state.select{|r| r.trips.active.size ==0}
(7.3ms) SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='rides'
Ride Load (1.6ms) SELECT "rides".* FROM "rides" WHERE (rides.workflow_state = 'active')
(2.9ms) SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='trips'
(1.3ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 9]]
(0.7ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 10]]
(0.7ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 11]]
(0.7ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 12]]
(0.8ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 13]]
(0.8ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 14]]
(0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 15]]
(0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 16]]
(0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 17]]
(0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 18]]
(0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 19]]
(0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 20]]
....
Add scopes on Ride with a group and having clause. It would check the count of all future trips of a ride and return the rides with 0 count.
Class Ride
scope :active_state, where(state: "active")
scope :with_nonactive_trips, -> (start_date = Date.today){ joins(:trips).
group("rides.id").
having( ["sum(trips.date > ?) = 0",start_date] ) }
end
Ride.active_state.with_nonactive_trips
# returns All the rides with state == active, alteast one trip and having no trips with date > Date.today
Using a lambda since you had it on the active scope in Trip. I am guessing you need to use a different date than Date.today for some queries.

Resources