Arel AND clause and empty state

Consider the following code snippet:

def sql billing_requests .project(billing_requests[Arel.star]) .where( filter_by_day .and(filter_by_merchant) .and(filter_by_operator_name) ) .to_sql end def filter_by_day billing_requests[:created_at].gteq(@start_date).and( billing_requests[:created_at].lteq(@end_date) ) end def filter_by_operator_name unless @operator_name.blank? return billing_requests[:operator_name].eq(@operator_name) end end def filter_by_merchant unless @merchant_id.blank? return billing_requests[:merchant_id].eq(@merchant_id) end end private def billing_requests @table ||= Arel::Table.new(:billing_requests) end 

In the filter_by_merchant method, when the seller ID becomes empty, what should be the value that should be returned for Arel to ignore the effect of the AND clause? Also, is there a better way to handle this?

+6
source share
3 answers

You must return true. When you run .and (true), it will eventually convert to 'AND 1' in sql.

 def filter_by_merchant return true if @merchant_id.blank? billing_requests[:merchant_id].eq(@merchant_id) end 
+6
source

It seems impossible to give any and arguments that make it do nothing. However, you can simply call and conditionally:

 def sql billing_requests .project(billing_requests[Arel.star]) .where(filter_by_day_and_merchant_and_operator_name) .to_sql end def filter_by_day billing_requests[:created_at].gteq(@start_date).and( billing_requests[:created_at].lteq(@end_date) ) end def filter_by_merchant billing_requests[:merchant_id].eq(@merchant_id) end def filter_by_operator_name billing_requests[:operator_name].eq(@operator_name) end def filter_by_day_and_merchant if @merchant_id.blank? filter_by_day else filter_by_day.and(filter_by_merchant) end end def filter_by_day_and_merchant_and_operator_name if @operator_name.blank? filter_by_day_and_merchant else filter_by_day_and_merchant.and(filter_by_operator_name) end end private def billing_requests @table ||= Arel::Table.new(:billing_requests) end 

This is very awkward, but he is doing his job.

+1
source
 def sql billing_requests .project(billing_requests[Arel.star]) .where(conditions) .to_sql end def conditions ret = filter_by_day ret = ret.and(filter_by_merchant) unless @merchant_id.blank? ret = ret.and(filter_by_operator_name) unless @operator_name.blank? ret end def filter_by_day billing_requests[:created_at].gteq(@start_date).and( billing_requests[:created_at].lteq(@end_date) ) end def filter_by_operator_name billing_requests[:operator_name].eq(@operator_name) end def filter_by_merchant billing_requests[:merchant_id].eq(@merchant_id) end private def billing_requests @table ||= Arel::Table.new(:billing_requests) end 
+1
source

Source: https://habr.com/ru/post/989437/


All Articles