mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 13:53:44 +08:00
Add Support for Arrays to CustomFields
This commit is contained in:
parent
e502122c51
commit
1e70c3cbbd
|
@ -8,35 +8,80 @@ module Concern
|
||||||
end
|
end
|
||||||
|
|
||||||
def custom_fields
|
def custom_fields
|
||||||
@custom_fields ||= begin
|
@custom_fields ||= refresh_custom_fields_from_db.dup
|
||||||
@custom_fields_orig = Hash[*_custom_fields.pluck(:name,:value).flatten]
|
|
||||||
@custom_fields_orig.dup
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def custom_fields=(data)
|
def custom_fields=(data)
|
||||||
custom_fields.replace(data)
|
custom_fields.replace(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def custom_fields_clean?
|
||||||
|
# Check whether the cached version has been
|
||||||
|
# changed on this model
|
||||||
|
!@custom_fields || @custom_fields_orig == @custom_fields
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def refresh_custom_fields_from_db
|
||||||
|
target = Hash.new
|
||||||
|
_custom_fields.pluck(:name,:value).each do |key, value|
|
||||||
|
if target.has_key? key
|
||||||
|
if !target[key].is_a? Array
|
||||||
|
target[key] = [target[key]]
|
||||||
|
end
|
||||||
|
target[key] << value
|
||||||
|
else
|
||||||
|
target[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@custom_fields_orig = target
|
||||||
|
@custom_fields = @custom_fields_orig.dup
|
||||||
|
end
|
||||||
|
|
||||||
def save_custom_fields
|
def save_custom_fields
|
||||||
if @custom_fields && @custom_fields_orig != @custom_fields
|
if !custom_fields_clean?
|
||||||
dup = @custom_fields.dup
|
dup = @custom_fields.dup
|
||||||
|
|
||||||
|
array_fields = {}
|
||||||
|
|
||||||
_custom_fields.each do |f|
|
_custom_fields.each do |f|
|
||||||
if dup[f.name] != f.value
|
if dup[f.name].is_a? Array
|
||||||
f.destroy
|
# we need to collect Arrays fully before
|
||||||
|
# we can compare them
|
||||||
|
if !array_fields.has_key? f.name
|
||||||
|
array_fields[f.name] = [f]
|
||||||
|
else
|
||||||
|
array_fields[f.name] << f
|
||||||
|
end
|
||||||
else
|
else
|
||||||
|
if dup[f.name] != f.value
|
||||||
|
f.destroy
|
||||||
|
else
|
||||||
|
dup.delete(f.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# let's iterate through our arrays and compare them
|
||||||
|
array_fields.each do |field_name, fields|
|
||||||
|
if fields.length == dup[field_name].length &&
|
||||||
|
fields.map{|f| f.value} == dup[field_name]
|
||||||
dup.delete(f.name)
|
dup.delete(f.name)
|
||||||
|
else
|
||||||
|
fields.each{|f| f.destroy }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
dup.each do |k,v|
|
dup.each do |k,v|
|
||||||
_custom_fields.create(name: k, value: v)
|
if v.is_a? Array
|
||||||
|
v.each {|subv| _custom_fields.create(name: k, value: subv)}
|
||||||
|
else
|
||||||
|
_custom_fields.create(name: k, value: v)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@custom_fields_orig = dup
|
refresh_custom_fields_from_db
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,6 +35,7 @@ describe Concern::HasCustomFields do
|
||||||
|
|
||||||
test_item.custom_fields["bob"] = "marley"
|
test_item.custom_fields["bob"] = "marley"
|
||||||
test_item.custom_fields["jack"] = "black"
|
test_item.custom_fields["jack"] = "black"
|
||||||
|
|
||||||
test_item.save
|
test_item.save
|
||||||
|
|
||||||
test_item = TestItem.find(test_item.id)
|
test_item = TestItem.find(test_item.id)
|
||||||
|
@ -51,6 +52,21 @@ describe Concern::HasCustomFields do
|
||||||
test_item.custom_fields.should == {"jack" => "jill"}
|
test_item.custom_fields.should == {"jack" => "jill"}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "casts integers to string without error" do
|
||||||
|
test_item = TestItem.new
|
||||||
|
test_item.custom_fields["a"].should == nil
|
||||||
|
test_item.custom_fields["a"] = 0
|
||||||
|
|
||||||
|
test_item.custom_fields["a"].should == 0
|
||||||
|
test_item.save
|
||||||
|
|
||||||
|
# should be casted right after saving
|
||||||
|
test_item.custom_fields["a"].should == "0"
|
||||||
|
|
||||||
|
test_item = TestItem.find(test_item.id)
|
||||||
|
test_item.custom_fields["a"].should == "0"
|
||||||
|
end
|
||||||
|
|
||||||
it "double save actually saves" do
|
it "double save actually saves" do
|
||||||
|
|
||||||
test_item = TestItem.new
|
test_item = TestItem.new
|
||||||
|
@ -66,6 +82,33 @@ describe Concern::HasCustomFields do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
it "handles arrays properly" do
|
||||||
|
|
||||||
|
test_item = TestItem.new
|
||||||
|
test_item.custom_fields = {"a" => ["b", "c", "d"]}
|
||||||
|
test_item.save
|
||||||
|
|
||||||
|
db_item = TestItem.find(test_item.id)
|
||||||
|
db_item.custom_fields.should == {"a" => ["b", "c", "d"]}
|
||||||
|
|
||||||
|
db_item.custom_fields["a"] = ["c", "d"]
|
||||||
|
db_item.save
|
||||||
|
db_item.custom_fields.should == {"a" => ["c", "d"]}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it "casts integers in arrays properly without error" do
|
||||||
|
|
||||||
|
test_item = TestItem.new
|
||||||
|
test_item.custom_fields = {"a" => ["b", 10, "d"]}
|
||||||
|
test_item.save
|
||||||
|
test_item.custom_fields.should == {"a" => ["b", "10", "d"]}
|
||||||
|
|
||||||
|
db_item = TestItem.find(test_item.id)
|
||||||
|
db_item.custom_fields.should == {"a" => ["b", "10", "d"]}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
it "simple modifications don't interfere" do
|
it "simple modifications don't interfere" do
|
||||||
test_item = TestItem.new
|
test_item = TestItem.new
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user