Fix OR condition in public taggings
In SQL, conditions like: ``` tag_id IN (x) AND taggable_type='Debate' OR taggable_type='Proposal' ``` Don't work as intended; we need to write: ``` tag_id IN (x) AND (taggable_type='Debate' OR taggable_type='Proposal') ``` Due to this bug, we were returning taggings for proposals without intending to do so. Since the code was very hard to read, we're also simplifying it.
This commit is contained in:
@@ -4,12 +4,10 @@ module ActsAsTaggableOn
|
||||
after_destroy :touch_taggable, :decrement_tag_custom_counter
|
||||
|
||||
scope :public_for_api, -> do
|
||||
where(%{taggings.tag_id in (?) and
|
||||
(taggings.taggable_type = 'Debate' and taggings.taggable_id in (?)) or
|
||||
(taggings.taggable_type = 'Proposal' and taggings.taggable_id in (?))},
|
||||
Tag.where("kind IS NULL or kind = ?", "category").pluck(:id),
|
||||
Debate.public_for_api.pluck(:id),
|
||||
Proposal.public_for_api.pluck(:id))
|
||||
where(
|
||||
tag: Tag.where(kind: [nil, "category"]),
|
||||
taggable: [Debate.public_for_api, Proposal.public_for_api]
|
||||
)
|
||||
end
|
||||
|
||||
def touch_taggable
|
||||
@@ -35,9 +33,10 @@ module ActsAsTaggableOn
|
||||
include Graphqlable
|
||||
|
||||
scope :public_for_api, -> do
|
||||
where("(tags.kind IS NULL or tags.kind = ?) and tags.id in (?)",
|
||||
"category",
|
||||
Tagging.public_for_api.distinct.pluck("taggings.tag_id"))
|
||||
where(
|
||||
kind: [nil, "category"],
|
||||
id: Tagging.public_for_api.distinct.pluck(:tag_id)
|
||||
)
|
||||
end
|
||||
|
||||
include PgSearch::Model
|
||||
|
||||
21
spec/models/tagging_spec.rb
Normal file
21
spec/models/tagging_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Tagging do
|
||||
describe ".public_for_api" do
|
||||
it "returns taggings for debates and proposals" do
|
||||
create(:tag, name: "Health", kind: nil)
|
||||
debate = create(:debate, tag_list: "Health")
|
||||
proposal = create(:proposal, tag_list: "Health")
|
||||
|
||||
expect(Tagging.public_for_api.map(&:taggable)).to match_array [debate, proposal]
|
||||
end
|
||||
|
||||
it "does not return taggings for other tag kinds" do
|
||||
create(:tag, name: "Health", kind: "custom")
|
||||
create(:debate, tag_list: "Health")
|
||||
create(:proposal, tag_list: "Health")
|
||||
|
||||
expect(Tagging.public_for_api.map(&:taggable)).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user