Sequelクエリですべてのデータセットを返す方法
概要
Rails スコープは nil ではなく all(ActiveRecord::Relation) を返します。 条件がnilの場合にメソッドチェーンを使用できるようにします。
class MyClass < ApplicationRecord
scope :my_filter, ->(condition) { where(condition: condition) if condition.present? }
end
MyClass.where(foo: 'foo').my_filter(condition).order(:date)
Sequel にも同様の機能を実装したいのですが、Sequel ではすべてが Array を返すため、このコードはうまく機能しません。 Rails スコープと同様の機能を Sequel で作成するにはどうすればよいですか?
class MyClass < Sequel::Model
dataset_module do
def my_filter(condition)
return all if condition.nil?
where(condition: condition)
end
end
end
解決策
where はデータセットを返すので、「すべて」も同じオブジェクトを返すことを希望していると思います。
識別したように、すべてが配列を返します。ただし、clone または self を使用してデータセットを取得できます。
したがって、実装を次のように変更するだけです。
class MyClass < Sequel::Model
datase_module do
def my_filter(condition)
return clone if condition.nil?
where(condition: condition)
end
end
end
動作例: https://replit.com/@engineersmnky/SequelGemRailsScope#main.rb
追加情報:
クローンを選択したのは、ほとんどのクエリ メソッドがこのメソッドを利用しているためです (ActiveRecord での生成と同様)。
データセット#cloneは次のようになります
def clone(opts = nil || (return self))
c = super(:freeze=>false)
c.opts.merge!(opts)
unless opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
c.clear_columns_cache
end
c.freeze
end
clone のメソッド シグネチャは、条件が渡されない場合に実行をショートカットし、単に self を返します。
コメントに記載されているように、
ただし、コメントには次のようにも書かれています
したがって、代わりに return self を使用することも選択できます。*
*上記の例では両方のオプションを実装して、それらの同一の機能に加えて、メソッド シグネチャが非常に興味深いことを示しました。