Note that there are some explanatory texts on larger screens.

plurals
  1. POQueryObject for Rails - how to encapsulate set of operations on ActiveRecord
    primarykey
    data
    text
    <p>How can I encapsulate a set of operations (most of which are essentially .where(...)) and apply it to different models, in a way that some of the models may not implement some of the operations and should return empty collections. (non-essential code skipped)</p> <p>What I have designed (but not satisfied with):</p> <pre><code>class ActivityFinder def self.find(query, limit = nil) activities = get_activities(query) activities = activities.sort_by(&amp;:created_at).reverse // some-kind of merge-sort activities = activities.slice(0, limit) if limit.present? activities end private def self.get_activities(query) activities = [] activities += query.apply(ModelA) activities += query.apply(ModelB) activities += query.apply(ModelC) activities end end class ActivityQuery def created_before(time) @created_before = time self end def created_after(time) @created_after = time self end def apply(activity) activity = activity.where("#{activity.table_name}.created_at &lt; ?", @created_before) if @created_before.present? activity = activity.where("#{activity.table_name}.created_at &gt;= ?", @created_after) if @created_after.present? // more operations, not all of them are suported by ModelC rescue NoMethodError return [] end end </code></pre> <p>Usage</p> <pre><code>query = ActivityQuery.new.created_before(last_time).with_hash(...) activities = ActivityFinder.find(query) </code></pre> <p>What I don't like:</p> <ul> <li>the rescue for NoMethodError</li> <li>if different models has different name for the field, it has to be handled as a <code>case</code> statement in the query, coupling in this way the query object with each of the models</li> </ul> <p>So I'm searching for suggestions for better implementation</p> <p><strong>UPDATE</strong></p> <p>The problem is I want to pass any object that I got from an ActiveModel, e.g. ActiveRecord::Relation, so I can't just define a module with the methods (and override when needed) and include it in the models I'm using. The question is more to point in the right direction for a clean design, and not about implementation details, which I'll figure out somehow</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload