As I know ActiveRecord does not provide the feature merging scopes with OR ( for the moment).
I think there is two options to deal with this feature :
1 - Create a scope that returns projects containing a video or with a first spin containing a default video :
scope :with_video, -> { joins(
'LEFT JOIN spins
ON spins.id = (
select p.id
from spins as p WHERE projects.id = p.project_id ORDER BY p.id LIMIT 1
)
JOIN videos on videos.project_id = projects.id
WHERE
spins.default_video IS NOT NULL
OR
videos.project_id IS NOT NULL
')
}
I think this solution is unreadable and it's difficult to maintain. I do not make some performance tests with this query, perhaps this one must be improved
2 - create 2 scopes and merge both results
scope :with_one_video, -> { joins(:videos) }
scope :with_spin_video, -> { joins('JOIN spins ON
spins.id = (
SELECT S.id
FROM spins as S
WHERE projects.id = S.project_id
ORDER BY S.id LIMIT 1
)').where('spins.default_video IS NOT NULL')}
def with_video
(with_one_video.to_a + with_spin_video.to_a).uniq
end
This one is better with reusable scopes but the second scope is still difficult to read. With this solution results has been return as an Array, it can be a disadvantage depending on the situation.
Edit: I'm interrested by all answers with differents solutions, improvments on sql queries or even replaced them by activerecord / arel