diff --git a/app/controllers/administrate/application_controller.rb b/app/controllers/administrate/application_controller.rb index 2296dfa78..826c51ec0 100644 --- a/app/controllers/administrate/application_controller.rb +++ b/app/controllers/administrate/application_controller.rb @@ -195,7 +195,9 @@ def sorting_params end def dashboard - @dashboard ||= dashboard_class.new + @dashboard ||= dashboard_class.new.tap do |d| + d.context = self + end end def requested_resource @@ -225,7 +227,7 @@ def apply_collection_includes(relation) def resource_params params.require(resource_class.model_name.param_key) - .permit(dashboard.permitted_attributes(action_name, self)) + .permit(dashboard.permitted_attributes(action_name)) .transform_values { |v| read_param_value(v) } end diff --git a/lib/administrate/base_dashboard.rb b/lib/administrate/base_dashboard.rb index 08333c55d..d54470244 100644 --- a/lib/administrate/base_dashboard.rb +++ b/lib/administrate/base_dashboard.rb @@ -51,7 +51,7 @@ def all_attributes attribute_types.keys end - def form_attributes(action = nil, _context = nil) + def form_attributes(action = nil) action = case action when "update" then "edit" @@ -69,8 +69,8 @@ def specific_form_attributes_for(action) self.class.const_get(cname) if self.class.const_defined?(cname) end - def permitted_attributes(action = nil, context = nil) - attributes = form_attributes(action, context) + def permitted_attributes(action = nil) + attributes = form_attributes(action) if attributes.is_a? Hash attributes = attributes.values.flatten @@ -126,6 +126,8 @@ def item_associations attribute_associated attributes end + attr_accessor :context + private def attribute_not_found_message(attr) diff --git a/lib/administrate/field/associative.rb b/lib/administrate/field/associative.rb index cf4865389..857c327c0 100644 --- a/lib/administrate/field/associative.rb +++ b/lib/administrate/field/associative.rb @@ -53,7 +53,9 @@ def html_controller private def associated_dashboard - "#{associated_class_name}Dashboard".constantize.new + "#{associated_class_name}Dashboard".constantize.new.tap do |d| + d.context = context + end end def primary_key diff --git a/lib/administrate/field/base.rb b/lib/administrate/field/base.rb index 65121587c..f5bdb71a5 100644 --- a/lib/administrate/field/base.rb +++ b/lib/administrate/field/base.rb @@ -97,6 +97,7 @@ def required? end attr_reader :attribute, :data, :options, :page, :resource + attr_accessor :context end end end diff --git a/lib/administrate/field/has_many.rb b/lib/administrate/field/has_many.rb index 775662215..348446404 100644 --- a/lib/administrate/field/has_many.rb +++ b/lib/administrate/field/has_many.rb @@ -26,7 +26,10 @@ def associated_collection(order = self.order) associated_dashboard, order: order, collection_attributes: options[:collection_attributes] - ) + ).tap do |page| + page.context = context + page.dashboard_context = context + end end def attribute_key diff --git a/lib/administrate/field/has_one.rb b/lib/administrate/field/has_one.rb index d4f5657f3..adb93fde5 100644 --- a/lib/administrate/field/has_one.rb +++ b/lib/administrate/field/has_one.rb @@ -34,14 +34,20 @@ def nested_form @nested_form ||= Administrate::Page::Form.new( resolver.dashboard_class.new, data || resolver.resource_class.new - ) + ).tap do |page| + page.context = context + page.dashboard_context = context + end end def nested_show @nested_show ||= Administrate::Page::Show.new( resolver.dashboard_class.new, data || resolver.resource_class.new - ) + ) do |page| + page.context = context + page.dashboard_context = context + end end def linkable? diff --git a/lib/administrate/field/polymorphic.rb b/lib/administrate/field/polymorphic.rb index 420ad11c1..78aba5e3d 100644 --- a/lib/administrate/field/polymorphic.rb +++ b/lib/administrate/field/polymorphic.rb @@ -26,7 +26,9 @@ def selected_global_id private def associated_dashboard(klass = data.class) - "#{klass.name}Dashboard".constantize.new + "#{klass.name}Dashboard".constantize.new.tap do |d| + d.context = context + end end def classes diff --git a/lib/administrate/page/base.rb b/lib/administrate/page/base.rb index 8f052e253..be7fbc1fe 100644 --- a/lib/administrate/page/base.rb +++ b/lib/administrate/page/base.rb @@ -29,11 +29,21 @@ def item_associations attr_accessor :context + def dashboard_context=(context) + dashboard.context = context + end + private def attribute_field(dashboard, resource, attribute_name, page) field = dashboard.attribute_type_for(attribute_name) - field.new(attribute_name, nil, page, resource: resource) + field.new(attribute_name, nil, page, resource: resource).tap do |f| + f.context = context + end + end + + def get_attribute_value(resource, attribute_name) + resource.public_send(attribute_name) end attr_reader :dashboard, :options diff --git a/lib/administrate/page/form.rb b/lib/administrate/page/form.rb index 0c8e18090..4305a1f5e 100644 --- a/lib/administrate/page/form.rb +++ b/lib/administrate/page/form.rb @@ -11,7 +11,7 @@ def initialize(dashboard, resource) attr_reader :resource def attributes(action = nil) - attributes = dashboard.form_attributes(action, context) + attributes = dashboard.form_attributes(action) if attributes.is_a? Array attributes = {"" => attributes} diff --git a/spec/dashboards/order_dashboard_spec.rb b/spec/dashboards/order_dashboard_spec.rb index df3ab2097..9d6cb2a88 100644 --- a/spec/dashboards/order_dashboard_spec.rb +++ b/spec/dashboards/order_dashboard_spec.rb @@ -19,11 +19,12 @@ context "when the user is not an admin" do it "not returns attributes with customer_id" do dashboard = OrderDashboard.new + dashboard.context = ctx_with_non_admin_user expect( - dashboard.permitted_attributes("new", ctx_with_non_admin_user) + dashboard.permitted_attributes("new") ).not_to include("customer_id") expect( - dashboard.permitted_attributes("create", ctx_with_non_admin_user) + dashboard.permitted_attributes("create") ).not_to include("customer_id") end end @@ -31,11 +32,12 @@ context "when the user is an admin" do it "returns attributes with customer_id" do dashboard = OrderDashboard.new + dashboard.context = ctx_with_admin_user expect( - dashboard.permitted_attributes("new", ctx_with_admin_user) + dashboard.permitted_attributes("new") ).to include("customer_id") expect( - dashboard.permitted_attributes("create", ctx_with_admin_user) + dashboard.permitted_attributes("create") ).to include("customer_id") end end @@ -52,11 +54,12 @@ context "when the user is not an admin" do it "not returns attributes with customer_id" do dashboard = OrderDashboard.new + dashboard.context = ctx_with_non_admin_user expect( - dashboard.permitted_attributes("edit", ctx_with_non_admin_user) + dashboard.permitted_attributes("edit") ).not_to include("customer_id") expect( - dashboard.permitted_attributes("update", ctx_with_non_admin_user) + dashboard.permitted_attributes("update") ).not_to include("customer_id") end end @@ -64,11 +67,12 @@ context "when the user is an admin" do it "also no returns attributes with customer_id" do dashboard = OrderDashboard.new + dashboard.context = ctx_with_admin_user expect( - dashboard.permitted_attributes("edit", ctx_with_admin_user) + dashboard.permitted_attributes("edit") ).not_to include("customer_id") expect( - dashboard.permitted_attributes("update", ctx_with_admin_user) + dashboard.permitted_attributes("update") ).not_to include("customer_id") end end diff --git a/spec/example_app/app/dashboards/order_dashboard.rb b/spec/example_app/app/dashboards/order_dashboard.rb index f9f058332..714832a1c 100644 --- a/spec/example_app/app/dashboards/order_dashboard.rb +++ b/spec/example_app/app/dashboards/order_dashboard.rb @@ -70,7 +70,7 @@ class OrderDashboard < Administrate::BaseDashboard ) .freeze - def form_attributes(action = nil, context = nil) + def form_attributes(action = nil) if %w[new create].include?(action.to_s) && context.try(:pundit_user).try(:admin?) super else diff --git a/spec/lib/fields/belongs_to_spec.rb b/spec/lib/fields/belongs_to_spec.rb index ff274e59c..e3b9ae30a 100644 --- a/spec/lib/fields/belongs_to_spec.rb +++ b/spec/lib/fields/belongs_to_spec.rb @@ -202,6 +202,9 @@ allow_any_instance_of(FooDashboard).to( receive(:display_resource).and_return(uuid) ) + allow_any_instance_of(FooDashboard).to( + receive(:context=).with(nil).and_return(nil) + ) end it "is the associated table key that matches our foreign key" do diff --git a/spec/lib/fields/has_many_spec.rb b/spec/lib/fields/has_many_spec.rb index 044a7aeee..301ef84b6 100644 --- a/spec/lib/fields/has_many_spec.rb +++ b/spec/lib/fields/has_many_spec.rb @@ -52,6 +52,7 @@ stub_const("FooDashboard", Class.new) allow(FooDashboard).to receive(:new).and_return(dashboard_double) + allow(dashboard_double).to receive(:context=).with(nil).and_return(nil) end it "determines what dashboard is used to present the association" do @@ -89,6 +90,9 @@ allow_any_instance_of(FooDashboard).to( receive(:display_resource).and_return(uuid) ) + allow_any_instance_of(FooDashboard).to( + receive(:context=).with(nil).and_return(nil) + ) end it "is the key matching the associated foreign key" do diff --git a/spec/lib/fields/polymorphic_spec.rb b/spec/lib/fields/polymorphic_spec.rb index e08cffbda..c4d215272 100644 --- a/spec/lib/fields/polymorphic_spec.rb +++ b/spec/lib/fields/polymorphic_spec.rb @@ -44,6 +44,7 @@ def display_resource(*) :success end + attr_accessor :context end field = Administrate::Field::Polymorphic.new(:foo, Thing.new, :show)