mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
Use method call directly instead of `public_send` with fixed argument. The cop is declared unsafe. I think that is because it can also replace `send` but we replace only `public_send` here.
262 lines
6.8 KiB
Ruby
262 lines
6.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Admin
|
|
class ResourceController < Spree::Admin::BaseController
|
|
helper_method :new_object_url, :edit_object_url, :object_url, :collection_url
|
|
before_action :load_resource, except: [:update_positions]
|
|
rescue_from ActiveRecord::RecordNotFound, with: :resource_not_found
|
|
rescue_from CanCan::AccessDenied, with: :unauthorized
|
|
|
|
respond_to :html
|
|
respond_to :js, except: [:show, :index]
|
|
|
|
def new
|
|
respond_with(@object) do |format|
|
|
format.html { render layout: !request.xhr? }
|
|
format.js { render layout: false }
|
|
end
|
|
end
|
|
|
|
def edit
|
|
respond_with(@object) do |format|
|
|
format.html { render layout: !request.xhr? }
|
|
format.js { render layout: false }
|
|
end
|
|
end
|
|
|
|
def create
|
|
@object.attributes = permitted_resource_params
|
|
if @object.save
|
|
flash[:success] = flash_message_for(@object, :successfully_created)
|
|
respond_with(@object) do |format|
|
|
format.html { redirect_to location_after_save }
|
|
format.js { render layout: false }
|
|
end
|
|
else
|
|
respond_with(@object)
|
|
end
|
|
end
|
|
|
|
def update
|
|
if @object.update(permitted_resource_params)
|
|
flash[:success] = flash_message_for(@object, :successfully_updated)
|
|
respond_with(@object) do |format|
|
|
format.html { redirect_to location_after_save }
|
|
format.js { render layout: false }
|
|
end
|
|
else
|
|
respond_with(@object)
|
|
end
|
|
end
|
|
|
|
def update_positions
|
|
params[:positions].each do |id, index|
|
|
model_class.where(id:).update_all(position: index)
|
|
end
|
|
|
|
respond_to do |format|
|
|
format.js { render plain: 'Ok' }
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
if @object.destroy
|
|
flash[:success] = flash_message_for(@object, :successfully_removed)
|
|
respond_with(@object) do |format|
|
|
format.html { redirect_to collection_url }
|
|
format.js { render partial: "spree/admin/shared/destroy" }
|
|
end
|
|
else
|
|
respond_with(@object) do |format|
|
|
format.html { redirect_to collection_url }
|
|
end
|
|
end
|
|
end
|
|
|
|
protected
|
|
|
|
def resource_not_found
|
|
flash[:error] = flash_message_for(model_class.new, :not_found)
|
|
redirect_to collection_url
|
|
end
|
|
|
|
class << self
|
|
attr_accessor :parent_data
|
|
|
|
def belongs_to(model_name, options = {})
|
|
@parent_data ||= {}
|
|
@parent_data[:model_name] = model_name
|
|
@parent_data[:model_class] = model_name.to_s.classify.constantize
|
|
@parent_data[:find_by] = options[:find_by] || :id
|
|
end
|
|
end
|
|
|
|
def model_class
|
|
controller_class_name.constantize
|
|
end
|
|
|
|
def model_name
|
|
parent_data[:model_name].gsub('spree/', '')
|
|
end
|
|
|
|
def object_name
|
|
controller_name.singularize
|
|
end
|
|
|
|
def load_resource
|
|
if member_action?
|
|
@object ||= load_resource_instance
|
|
|
|
# call authorize! a third time (called twice already in Admin::BaseController)
|
|
# this time we pass the actual instance so fine-grained abilities can control
|
|
# access to individual records, not just entire models.
|
|
authorize! action, @object
|
|
|
|
instance_variable_set("@#{object_name}", @object)
|
|
|
|
# If we don't have access, clear the object
|
|
unless can? action, @object
|
|
instance_variable_set("@#{object_name}", nil)
|
|
end
|
|
|
|
authorize! action, @object
|
|
else
|
|
@collection ||= collection
|
|
|
|
# note: we don't call authorize here as the collection method should use
|
|
# CanCan's accessible_by method to restrict the actual records returned
|
|
|
|
instance_variable_set("@#{controller_name}", @collection)
|
|
end
|
|
end
|
|
|
|
def load_resource_instance
|
|
if new_actions.include?(action)
|
|
build_resource
|
|
elsif params[:id]
|
|
find_resource
|
|
end
|
|
end
|
|
|
|
def parent_data
|
|
self.class.parent_data
|
|
end
|
|
|
|
def parent
|
|
return nil if parent_data.blank?
|
|
|
|
@parent ||= parent_data[:model_class].
|
|
find_by(parent_data[:find_by] => params["#{model_name}_id"])
|
|
instance_variable_set("@#{model_name}", @parent)
|
|
end
|
|
|
|
def find_resource
|
|
if parent_data.present?
|
|
parent.public_send(controller_name).find(params[:id])
|
|
else
|
|
model_class.find(params[:id])
|
|
end
|
|
end
|
|
|
|
def build_resource
|
|
if parent_data.present?
|
|
parent.public_send(controller_name).build
|
|
else
|
|
model_class.new
|
|
end
|
|
end
|
|
|
|
def collection
|
|
return parent.public_send(controller_name) if parent_data.present?
|
|
|
|
if model_class.respond_to?(:accessible_by) &&
|
|
!current_ability.has_block?(params[:action], model_class)
|
|
model_class.accessible_by(current_ability, action)
|
|
else
|
|
model_class.scoped
|
|
end
|
|
end
|
|
|
|
def location_after_save
|
|
collection_url
|
|
end
|
|
|
|
# URL helpers
|
|
def new_object_url(options = {})
|
|
if parent_data.present?
|
|
url_helper.new_polymorphic_url([:admin, parent, model_class], options)
|
|
else
|
|
url_helper.new_polymorphic_url([:admin, model_class], options)
|
|
end
|
|
end
|
|
|
|
def edit_object_url(object, options = {})
|
|
if parent_data.present?
|
|
url_helper.public_send "edit_admin_#{model_name}_#{object_name}_url",
|
|
parent, object, options
|
|
else
|
|
url_helper.public_send "edit_admin_#{object_name}_url",
|
|
object, options
|
|
end
|
|
end
|
|
|
|
def object_url(object = nil, options = {})
|
|
target = object || @object
|
|
if parent_data.present?
|
|
url_helper.public_send "admin_#{model_name}_#{object_name}_url", parent, target, options
|
|
else
|
|
url_helper.public_send "admin_#{object_name}_url", target, options
|
|
end
|
|
end
|
|
|
|
# Permit specific list of params
|
|
#
|
|
# Example: params.require(object_name).permit(:name)
|
|
def permitted_resource_params
|
|
raise "All extending controllers need to override the method permitted_resource_params"
|
|
end
|
|
|
|
def collection_url(options = {})
|
|
if parent_data.present?
|
|
url_helper.polymorphic_url([:admin, parent, model_class], options)
|
|
else
|
|
url_helper.polymorphic_url([:admin, model_class], options)
|
|
end
|
|
end
|
|
|
|
def collection_actions
|
|
[:index]
|
|
end
|
|
|
|
def member_action?
|
|
collection_actions.exclude? action
|
|
end
|
|
|
|
def new_actions
|
|
[:new, :create]
|
|
end
|
|
|
|
private
|
|
|
|
def controller_class_name
|
|
if spree_controller?
|
|
"Spree::#{controller_name.classify}"
|
|
else
|
|
controller_name.classify.to_s
|
|
end
|
|
end
|
|
|
|
def url_helper
|
|
if spree_controller?
|
|
spree
|
|
else
|
|
main_app
|
|
end
|
|
end
|
|
|
|
def spree_controller?
|
|
controller_path.starts_with? "spree"
|
|
end
|
|
end
|
|
end
|