From e6e03a1a9612a57e78b6b4e4137cfe3625d0111f Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 25 Apr 2014 14:10:54 +0200 Subject: [PATCH] move custom fields into its own concern --- app/models/user.rb | 31 +------- lib/concern/has_custom_fields.rb | 39 +++++++++ .../concern/has_custom_fields_spec.rb | 79 +++++++++++++++++++ 3 files changed, 120 insertions(+), 29 deletions(-) create mode 100644 lib/concern/has_custom_fields.rb create mode 100644 spec/components/concern/has_custom_fields_spec.rb diff --git a/app/models/user.rb b/app/models/user.rb index 5ee6a10c5..a7f02c5af 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -8,10 +8,12 @@ require_dependency 'post_destroyer' require_dependency 'user_name_suggester' require_dependency 'pretty_text' require_dependency 'url_helper' +require_dependency 'concern/has_custom_fields' class User < ActiveRecord::Base include Roleable include UrlHelper + include Concern::HasCustomFields has_many :posts has_many :notifications, dependent: :destroy @@ -31,7 +33,6 @@ class User < ActiveRecord::Base has_many :invites, dependent: :destroy has_many :topic_links, dependent: :destroy has_many :uploads - has_many :user_custom_fields, dependent: :destroy has_one :facebook_user_info, dependent: :destroy has_one :twitter_user_info, dependent: :destroy @@ -69,7 +70,6 @@ class User < ActiveRecord::Base after_save :update_tracked_topics after_save :clear_global_notice_if_needed - after_save :save_custom_fields after_create :create_email_token after_create :create_user_stat @@ -589,35 +589,8 @@ class User < ActiveRecord::Base nil end - def custom_fields - @custom_fields ||= begin - @custom_fields_orig = Hash[*user_custom_fields.pluck(:name,:value).flatten] - @custom_fields_orig.dup - end - end - protected - def save_custom_fields - if @custom_fields && @custom_fields_orig != @custom_fields - dup = @custom_fields.dup - - user_custom_fields.each do |f| - if dup[f.name] != f.value - f.destroy - else - dup.remove[f.name] - end - end - - dup.each do |k,v| - user_custom_fields.create(name: k, value: v) - end - - @custom_fields_orig = @custom_fields - end - end - def cook if bio_raw.present? self.bio_cooked = PrettyText.cook(bio_raw, omit_nofollow: self.has_trust_level?(:leader)) if bio_raw_changed? diff --git a/lib/concern/has_custom_fields.rb b/lib/concern/has_custom_fields.rb new file mode 100644 index 000000000..18273af10 --- /dev/null +++ b/lib/concern/has_custom_fields.rb @@ -0,0 +1,39 @@ +module Concern + module HasCustomFields + extend ActiveSupport::Concern + + included do + has_many :_custom_fields, dependent: :destroy, :class_name => "#{name}CustomField" + after_save :save_custom_fields + end + + def custom_fields + @custom_fields ||= begin + @custom_fields_orig = Hash[*_custom_fields.pluck(:name,:value).flatten] + @custom_fields_orig.dup + end + end + + protected + + def save_custom_fields + if @custom_fields && @custom_fields_orig != @custom_fields + dup = @custom_fields.dup + + _custom_fields.each do |f| + if dup[f.name] != f.value + f.destroy + else + dup.remove[f.name] + end + end + + dup.each do |k,v| + _custom_fields.create(name: k, value: v) + end + + @custom_fields_orig = @custom_fields + end + end + end +end \ No newline at end of file diff --git a/spec/components/concern/has_custom_fields_spec.rb b/spec/components/concern/has_custom_fields_spec.rb new file mode 100644 index 000000000..176e1c0cc --- /dev/null +++ b/spec/components/concern/has_custom_fields_spec.rb @@ -0,0 +1,79 @@ +require "spec_helper" +require_dependency "concern/has_custom_fields" + +describe Concern::HasCustomFields do + + context "custom_fields" do + before do + + Topic.exec_sql("create temporary table test_items(id SERIAL primary key)") + Topic.exec_sql("create temporary table test_item_custom_fields(id SERIAL primary key, test_item_id int, name varchar(256) not null, value text)") + + class TestItem < ActiveRecord::Base + include Concern::HasCustomFields + end + + class TestItemCustomField < ActiveRecord::Base + belongs_to :test_item + end + end + + after do + Topic.exec_sql("drop table test_items") + Topic.exec_sql("drop table test_item_custom_fields") + + # import is making my life hard, we need to nuke this out of orbit + des = ActiveSupport::DescendantsTracker.class_variable_get :@@direct_descendants + des[ActiveRecord::Base].delete(TestItem) + des[ActiveRecord::Base].delete(TestItemCustomField) + end + + it "simple modification of custom fields" do + test_item = TestItem.new + + test_item.custom_fields["a"].should == nil + + test_item.custom_fields["bob"] = "marley" + test_item.custom_fields["jack"] = "black" + test_item.save + + test_item = TestItem.find(test_item.id) + + test_item.custom_fields["bob"].should == "marley" + test_item.custom_fields["jack"].should == "black" + + test_item.custom_fields.delete("bob") + test_item.custom_fields["jack"] = "jill" + + test_item.save + test_item = TestItem.find(test_item.id) + + test_item.custom_fields.should == {"jack" => "jill"} + end + + + it "simple modifications don't interfere" do + test_item = TestItem.new + + test_item.custom_fields["a"].should == nil + + test_item.custom_fields["bob"] = "marley" + test_item.custom_fields["jack"] = "black" + test_item.save + + test_item2 = TestItem.new + + test_item2.custom_fields["x"].should == nil + + test_item2.custom_fields["sixto"] = "rodriguez" + test_item2.custom_fields["de"] = "la playa" + test_item2.save + + test_item = TestItem.find(test_item.id) + test_item2 = TestItem.find(test_item2.id) + + test_item.custom_fields.should == {"jack" => "black", "bob" => "marley"} + test_item2.custom_fields.should == {"sixto" => "rodriguez", "de" => "la playa"} + end + end +end