Commit 0e627fc8 by Ivan Lan

Update scope & Support :prefix to association methods

parent e23bc7b1
......@@ -11,26 +11,32 @@ module ActsAsPasting
# ary => [obj, obj]
scope :pasted_with_any, ->(ary, prefix: '') {
ary = parsed_condition_ary(ary)
ids = ary.map do |klass, id|
joins(:pastings).where(acts_as_pasting_pastings: {
pasted_type: klass.constantize.base_class.name, pasted_id: id, type: prefix
}).pluck(:id)
end.reduce(:|)
where(id: ids)
arel = Arel::Table.new(:acts_as_pasting_pastings, as: "acts_as_pasting_pastings_#{SecureRandom.hex(10)}")
source_arel = arel_table
join_condition = ary.group_by(&:first).map do |(klass, value)|
ids = value.map(&:last)
arel[:pasted_type].eq(klass.constantize.base_class.name).
and(arel[:pasted_id].in(ids)).
and(arel[:pasteable_id].eq(source_arel[:id])).
and((arel[:type].eq(prefix))
end.reduce(:or)
joins(arel.join(arel).on(join_condition).join_sources).distinct
}
scope :pasted_with_all, ->(ary, prefix: '') {
ary = parsed_condition_ary(ary)
ids = ary.map do |klass, id|
joins(:pastings).where(acts_as_pasting_pastings: {
pasted_type: klass.constantize.base_class.name, pasted_id: id, type: prefix
}).pluck(:id)
end.reduce(:&)
where(id: ids)
ary.reduce(where(nil)) do |association, value|
association.pasted_with_any([value], prefix: prefix)
end
}
end
module ClassMethods
def acts_as_pastable associations, options={}, prefix: ''
pasting_name = prefix.blank? ? :pastings : [prefix, 'pastings'].join('_').to_sym
has_many pasting_name, as: :pasteable, class_name: 'ActsAsPasting::Pasting'
has_many associations, through: pasting_name, source: :pasted, **options
end
end
end
end
module ActsAsPasting
module Pasteable
extend ActiveSupport::Concern
# 带 prefix 的 pasted_with,独立于不带 prefix 的之外
included do
has_many :pastings, as: :pasteable, class_name: 'ActsAsPasting::Pasting'
has_many :hosts, through: :pastings
# ary => [[klass, id], [klass, id]]
# ary => [obj, obj]
scope :pasted_with_any, ->(ary, prefix: '') {
ary = parsed_condition_ary(ary)
ids = ary.map do |klass, id|
joins(:pastings).where(acts_as_pasting_pastings: {
pasted_type: klass.constantize.base_class.name, pasted_id: id, type: prefix
}).pluck(:id)
end.reduce(:|)
where(id: ids)
}
scope :pasted_with_all, ->(ary, prefix: '') {
ary = parsed_condition_ary(ary)
ids = ary.map do |klass, id|
joins(:pastings).where(acts_as_pasting_pastings: {
pasted_type: klass.constantize.base_class.name, pasted_id: id, type: prefix
}).pluck(:id)
end.reduce(:&)
where(id: ids)
}
end
module ClassMethods
def acts_as_pastable associations, options={}
has_many :pastings, as: :pasteable, class_name: 'ActsAsPasting::Pasting'
has_many associations, through: :pastings, source: :pasted, **options
end
end
end
end
......@@ -9,22 +9,23 @@ module ActsAsPasting
# ary => [obj, obj]
scope :pasted_with_any, ->(ary, prefix: '') {
ary = parsed_condition_ary(ary)
ids = ary.map do |klass, id|
joins(:pastings).where(acts_as_pasting_pastings: {
pasteable_type: klass.constantize.base_class.name, pasteable_id: id, type: prefix
}).pluck(:id)
end.reduce(:|)
where(id: ids)
arel = Arel::Table.new(:acts_as_pasting_pastings, as: "acts_as_pasting_pastings_#{SecureRandom.hex(10)}")
source_arel = arel_table
join_condition = ary.group_by(&:first).map do |(klass, value)|
ids = value.map(&:last)
arel[:pasteable_type].eq(klass.constantize.base_class.name).
and(arel[:pasteable_id].in(ids)).
and(arel[:pasted_id].eq(source_arel[:id])).
and((arel[:type].eq(prefix))
end.reduce(:or)
joins(arel.join(arel).on(join_condition).join_sources).distinct
}
scope :pasted_with_all, ->(ary, prefix: '') {
ary = parsed_condition_ary(ary)
ids = ary.map do |klass, id|
joins(:pastings).where(acts_as_pasting_pastings: {
pasteable_type: klass.constantize.base_class.name, pasteable_id: id, type: prefix
}).pluck(:id)
end.reduce(:&)
where(id: ids)
ary.reduce(where(nil)) do |association, value|
association.pasted_with_any([value], prefix: prefix)
end
}
after_create :save_paste_list
......@@ -200,8 +201,10 @@ module ActsAsPasting
end
end
def acts_as_pasted associations, options={}
has_many associations, through: :pastings, source: :pasteable, **options
def acts_as_pasted associations, options={}, prefix: ''
pasting_name = prefix.blank? ? :pastings : [prefix, 'pastings'].join('_').to_sym
has_many pasting_name, -> { where(type: prefix) }, class_name: 'ActsAsPasting::Pasting', as: :pasted
has_many associations, through: pasting_name, source: :pasteable, **options
end
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment