Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: ActiveRecord where vs merge

First, I am getting the review statuses between particular dates.

date_range = Date.parse(@from_date).beginning_of_day..Date.parse(@to_date).end_of_day

@review_statuses = ReviewStatus.where(updated_at: date_range)

Next, I need to apply an 'AND' condition.

    @review_cycle = params[:review_cycle]

    if @review_cycle.present?
      @review_statuses = @review_statuses.merge(
                           ReviewStatus.where(evidence_cycle: @review_cycle)
                                       .or(ReviewStatus.where(roc_cycle: @review_cycle)))
    end

Now for the below should I apply a 'where' or 'merge'.

@status = params[:status]

@review_statuses.where(evidence_status: :pass, roc_status: :pass) if @status == 'pass'

Can someone explain, when should we use merge instead of where?

like image 531
Rajkaran Mishra Avatar asked May 23 '18 13:05

Rajkaran Mishra


People also ask

What is Merge in Rails?

merge(other) public. Merges in the conditions from other, if other is an ActiveRecord::Relation. Returns an array representing the intersection of the resulting records with other, if other is an array.

What does where return in rails?

The where method allows you to specify conditions to limit the records returned, representing the WHERE -part of the SQL statement. Conditions can either be specified as a string, array, or hash.

What is ActiveRecord in Ruby on Rails?

1 What is Active Record? Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.


1 Answers

You generally want to use where except in special circumstances -- most commonly, to apply conditions to a secondary (joined) table in the query. This is becase

  1. it's shorter / clearer / more idiomatic, and
  2. merge has tricky edge cases: it mostly combines the two queries, but there are situations where one side's value will just override the other.

Given that, even your existing condition doesn't need merge:

# Unchanged
date_range = Date.parse(@from_date).beginning_of_day..Date.parse(@to_date).end_of_day
@review_statuses = ReviewStatus.where(updated_at: date_range)

# direct #where+#or over #merge
@review_cycle = params[:review_cycle]
if @review_cycle.present?
  @review_statuses = @review_statuses.where(evidence_cycle: @review_cycle).or(
                       @review_statuses.where(roc_cycle: @review_cycle))
end

# more #where
@status = params[:status]
@review_statuses = @review_statuses.where(evidence_status: :pass, roc_status: :pass) if @status == 'pass'
like image 149
matthewd Avatar answered Oct 22 '22 07:10

matthewd