diff --git a/extensions/custom_field/preloader.rb b/extensions/custom_field/preloader.rb new file mode 100644 index 00000000..732dccf9 --- /dev/null +++ b/extensions/custom_field/preloader.rb @@ -0,0 +1,17 @@ +module CustomWizardCustomFieldPreloader + def preload_custom_fields(objects, fields) + if objects.present? + @cw_klass = objects.first.class.name.underscore + if cw_fields.any? + cw_fields.each do |field| + fields << field.name + end + end + end + super(objects, fields) + end + + def cw_fields + @cw_fields ||= CustomWizard::CustomField.list_by(:klass, @cw_klass) + end +end \ No newline at end of file diff --git a/extensions/custom_field/serializer.rb b/extensions/custom_field/serializer.rb new file mode 100644 index 00000000..31576c0a --- /dev/null +++ b/extensions/custom_field/serializer.rb @@ -0,0 +1,32 @@ +module CustomWizardCustomFieldSerializer + def attributes(*args) + hash = super + @cw_klass = get_cw_class + + if cw_fields.any? + cw_fields.each do |field| + if @cw_klass == "topic_view" + hash[field.name.to_sym] = object.topic.custom_fields["#{field.name}"] + else + hash[field.name.to_sym] = object.custom_fields["#{field.name}"] + end + end + end + + hash + end + + private + + def cw_fields + @cw_fields ||= CustomWizard::CustomField.list_by(:serializers, @cw_klass) + end + + def get_cw_class + self.class.ancestors.map do |klass| + klass.to_s.underscore.gsub("_serializer", "") + end.select do |klass| + CustomWizard::CustomField.serializers.include?(klass) + end.first + end +end \ No newline at end of file diff --git a/plugin.rb b/plugin.rb index 1a1dfba7..772bd62c 100644 --- a/plugin.rb +++ b/plugin.rb @@ -80,6 +80,8 @@ after_initialize do ../extensions/users_controller.rb ../extensions/wizard_field.rb ../extensions/wizard_step.rb + ../extensions/custom_field/preloader.rb + ../extensions/custom_field/serializer.rb ].each do |path| load File.expand_path(path, __FILE__) end @@ -174,35 +176,12 @@ after_initialize do .register_custom_field_type(field.name, field.type.to_sym) end end - end - - module CustomWizardCustomFieldSerialization - def attributes(*args) - hash = super - @cw_klass = self.class.name.underscore.gsub("_serializer", "") - - if cw_fields.any? - cw_fields.each do |field| - if @cw_klass == "topic_view" - hash[field.name.to_sym] = object.topic.custom_fields["#{field.name}"] - else - hash[field.name.to_sym] = object.custom_fields["#{field.name}"] - end - end - end - - hash - end - private - - def cw_fields - @cw_fields ||= CustomWizard::CustomField.list_by(:serializers, @cw_klass) - end + klass.to_s.classify.constantize.singleton_class.prepend CustomWizardCustomFieldPreloader end CustomWizard::CustomField.serializers.each do |serializer_klass| - "#{serializer_klass}_serializer".classify.constantize.prepend CustomWizardCustomFieldSerialization + "#{serializer_klass}_serializer".classify.constantize.prepend CustomWizardCustomFieldSerializer end DiscourseEvent.trigger(:custom_wizard_ready) diff --git a/spec/requests/custom_wizard/custom_field_extensions_spec.rb b/spec/requests/custom_wizard/custom_field_extensions_spec.rb new file mode 100644 index 00000000..d8c89f14 --- /dev/null +++ b/spec/requests/custom_wizard/custom_field_extensions_spec.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe "custom field extensions" do + let!(:topic) { Fabricate(:topic) } + let!(:post) { Fabricate(:post) } + let!(:category) { Fabricate(:category) } + let!(:user) { Fabricate(:user) } + let!(:group) { Fabricate(:group, users: [user]) } + + let(:custom_field_json) { + JSON.parse(File.open( + "#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/custom_field/custom_fields.json" + ).read) + } + + before do + custom_field_json['custom_fields'].each do |field_json| + custom_field = CustomWizard::CustomField.new(nil, field_json) + custom_field.save + end + end + + it "adds topic custom fields to the show topic response" do + topic.custom_fields["topic_field_1"] = true + topic.save_custom_fields(true) + + get "/t/#{topic.slug}/#{topic.id}.json" + + expect(response.status).to eq(200) + expect(response.parsed_body["topic_field_1"]).to eq(true) + end + + it "adds category custom fields to the show categories response" do + category.custom_fields["category_field_1"] = { a: 1, b: 2 } + category.save_custom_fields(true) + + get "/c/#{category.id}/show.json" + + expect(response.status).to eq(200) + expect(response.parsed_body["category"]["category_field_1"]).to eq({ a: 1, b: 2 }.as_json) + end + + it "adds group custom fields to the show group response" do + group.custom_fields["group_field_1"] = "Group cf entry" + group.save_custom_fields(true) + + sign_in(user) + get "/groups/#{group.name}.json" + + expect(response.status).to eq(200) + expect(response.parsed_body['group']['group_field_1']).to eq("Group cf entry") + end + + it "adds post custom fields to the show post response" do + post.custom_fields["post_field_1"] = 7 + post.save_custom_fields(true) + + get "/posts/#{post.id}.json" + + expect(response.status).to eq(200) + expect(response.parsed_body['post_field_1']).to eq(7) + end + + context "preloaded" do + it "preloads category custom fields on site categories" do + Site.preloaded_category_custom_fields << "other_field" + + category.custom_fields["category_field_1"] = { a: 1, b: 2 } + category.save_custom_fields(true) + + get "/site.json" + expect(response.status).to eq(200) + + site_category = response.parsed_body['categories'].select { |c| c['id'] == category.id }.first + expect(site_category["category_field_1"]).to eq({ a: 1, b: 2 }.as_json) + end + + it "preloads group custom fields on group index" do + Group.preloaded_custom_field_names << "other_field" + + group = Fabricate(:group) + group.custom_fields["group_field_1"] = "Group cf entry" + group.save_custom_fields(true) + + get "/groups.json" + expect(response.status).to eq(200) + + group = response.parsed_body['groups'].select { |g| g['id'] == group.id }.first + expect(group['group_field_1']).to eq("Group cf entry") + end + end +end + \ No newline at end of file