includes is used for eager loading, so I assume you want load MyObjectTime
records along with user_my_object_time_matches
associations, so you don't have to query the database anymore.
The way that includes work is this:
MyObjectTime.where(search_criteria.join(' and '))includes(:user_my_object_time_matches)
That would query the database twice:
load all MyObjectTime records, subject to the search_criteria
SELECT * FROM my_object_times WHERE (....)
load all associated UserMyObjectTimeMachine
records
SELECT * FROM user_my_object_time_machines WHERE my_object_time_id IN ( [ids returned by the previous query ])
So if you want to add additional filtering on the second query, then in the model MyObjectTime
you can add another association:
class MyObjectTime < ActiveRecord::Base
...
has_many :user_my_object_time_matches
has_many :user_my_object_time_matches_with_null_user, -> { where("user_id IS NULL or user_id = 30") }, class_name: "UserMyObjectMatch"
and then when you call
MyObjectTime.where(search_criteria.join(' and ')).includes(:user_my_object_time_matches_with_null_user)
the second query will look like this:
SELECT * FROM user_my_object_time_machines WHERE (user_id IS NULL OR user_id = 30) AND my_object_time_id IN ( [ids returned by the previous query ])
With that your example would look like this:
@results = MyObjectTime.joins(:race)
.where( search_criteria.join(' and '), *search_values )
.limit(1000)
.order("my_objects.day DESC, my_objects.name")
.paginate(:page => params[:page])
.includes(:user_my_object_time_matches_with_null_user)
With no eager loading
If the condition is not the same everytime (user_id IS NULL OR user_id = 30), then I don't know a good way to eager load everything. So you can just use normal left join, but then query would be performed when you try to get the association records:
@results = MyObjectTime.joins(:race,
"LEFT JOIN user_my_object_time_matches on my_object_times.id = user_my_object_time_matches.my_object_time_id AND (user_my_object_time_matches.user_id IS NULL or user_my_object_time_matches.user_id = 30)")
.where( search_criteria.join(' and '), *search_values )
.limit(1000)
.order("my_objects.day DESC, my_objects.name")
.paginate(:page => params[:page])
.includes(:user_my_object_time_matches)
You can find good chunk of documentation in the Eager Loading of associations here:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html