module Refinery::Crud::ClassMethods
Public Instance Methods
crudify(model_name, options = {})
click to toggle source
# File lib/refinery/crud.rb, line 50 def crudify(model_name, options = {}) options = ::Refinery::Crud.default_options(model_name).merge(options) class_name = options[:class_name] singular_name = options[:singular_name] plural_name = options[:plural_name] module_eval %( def self.crudify_options #{options.inspect} end prepend_before_action :find_#{singular_name}, :only => [:update, :destroy, :edit, :show] prepend_before_action :merge_position_into_params!, :only => :create def new @#{singular_name} = #{class_name}.new end def create @#{singular_name} = #{class_name}.new(#{singular_name}_params) if @#{singular_name}.save flash.notice = t( 'refinery.crudify.created', :what => "'\#{@#{singular_name}.#{options[:title_attribute]}}'" ) create_or_update_successful else create_or_update_unsuccessful 'new' end end def edit # object gets found by find_#{singular_name} function end def update if @#{singular_name}.update_attributes(#{singular_name}_params) flash.notice = t( 'refinery.crudify.updated', :what => "'\#{@#{singular_name}.#{options[:title_attribute]}}'" ) create_or_update_successful else create_or_update_unsuccessful 'edit' end end def destroy # object gets found by find_#{singular_name} function title = @#{singular_name}.#{options[:title_attribute]} if @#{singular_name}.destroy flash.notice = t('destroyed', :scope => 'refinery.crudify', :what => "'\#{title}'") end redirect_to redirect_url end # Finds one single result based on the id params. def find_#{singular_name} @#{singular_name} = find_#{singular_name}_scope.find(params[:id]) end def find_#{singular_name}_scope _finder_scope = #{class_name}.includes(#{options[:include].map(&:to_sym).inspect}) _finder_scope = _finder_scope.friendly if _finder_scope.respond_to?(:friendly) _finder_scope end # Find the collection of @#{plural_name} based on the conditions specified into crudify # It will be ordered based on the conditions specified into crudify # And eager loading is applied as specified into crudify. def find_all_#{plural_name}(conditions = #{options[:conditions].inspect}) @#{plural_name} = find_#{singular_name}_scope .where(conditions) .order("#{options[:order]}") end def merge_position_into_params! # if the position field exists, set this object as last object, given the conditions of this class. if #{class_name}.column_names.include?("position") && params[:#{singular_name}][:position].nil? params[:#{singular_name}].merge!({ position: ((#{class_name}.where(#{options[:conditions].inspect}).maximum(:position)||-1) + 1) }) end end # Paginate a set of @#{plural_name} that may/may not already exist. def paginate_all_#{plural_name} # If we have already found a set then we don't need to again find_all_#{plural_name} if @#{plural_name}.nil? @#{plural_name} = @#{plural_name}.paginate(:page => params[:page], :per_page => paginate_per_page) end def paginate_per_page if #{options[:per_page].present?.inspect} #{options[:per_page].inspect} elsif #{class_name}.methods.map(&:to_sym).include?(:per_page) #{class_name}.per_page end end def redirect_url if params[:page].present? page = params[:page].to_i rescue 1 page -= 1 while #{class_name}.paginate(:page => page).empty? && page > 1 #{options[:redirect_to_url]}(:page => page) else #{options[:redirect_to_url]} end end # If the controller is being accessed via an ajax request # then render only the collection of items. def render_partial_response? if request.xhr? render plain: render_to_string(partial: '#{plural_name}', layout: false).html_safe, layout: 'refinery/flash' and return false end end def create_or_update_successful if from_dialog? self.index @dialog_successful = true render :index else if /true|on|1/ === params[:continue_editing] if request.xhr? render :partial => '/refinery/message' else redirect_to :back end else redirect_back_or_default redirect_url end end end def create_or_update_unsuccessful(action) if request.xhr? render :partial => '/refinery/admin/error_messages', :locals => { :object => @#{singular_name}, :include_object_name => true } else render :action => action end end # Returns a weighted set of results based on the query specified by the user. def search_all_#{plural_name} # First find normal results. find_all_#{plural_name}(#{options[:search_conditions].inspect}) # Now get weighted results by running the query against the results already found. @#{plural_name} = @#{plural_name}.with_query(params[:search]) end def #{singular_name}_params raise "Please override #{singular_name}_params with your desired parameter security." end # Ensure all methods are protected so that they should only be called # from within the current controller. protected :find_#{singular_name}, :find_#{singular_name}_scope, :find_all_#{plural_name}, :paginate_all_#{plural_name}, :paginate_per_page, :render_partial_response?, :search_all_#{plural_name}, :#{singular_name}_params, :redirect_url, :create_or_update_successful, :create_or_update_unsuccessful, :merge_position_into_params! ), __FILE__, __LINE__ # Methods that are only included when this controller is searchable. if options[:searchable] if options[:paging] module_eval %( def index search_all_#{plural_name} if searching? paginate_all_#{plural_name} render_partial_response? end ), __FILE__, __LINE__ else module_eval %( def index if searching? search_all_#{plural_name} else find_all_#{plural_name} end render_partial_response? end ), __FILE__, __LINE__ end else if options[:paging] module_eval %( def index paginate_all_#{plural_name} render_partial_response? end ), __FILE__, __LINE__ else module_eval %( def index find_all_#{plural_name} render_partial_response? end ), __FILE__, __LINE__ end end if options[:sortable] module_eval %( def reorder find_all_#{plural_name} end # Based upon https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop def update_positions previous = nil params.to_unsafe_h[:ul].each do |_, list| list.each do |index, hash| moved_item_id = hash['id'][/\\d+\\z/] @current_#{singular_name} = #{class_name}.find_by_id(moved_item_id) if @current_#{singular_name}.respond_to?(:move_to_root) if previous.present? @current_#{singular_name}.move_to_right_of(#{class_name}.find_by_id(previous)) elsif !@current_#{singular_name}.root? @current_#{singular_name}.move_to_root end else @current_#{singular_name}.update_columns position: index end if hash['children'].present? update_child_positions(hash, @current_#{singular_name}) end previous = moved_item_id end end #{class_name}.rebuild! if #{class_name}.respond_to?(:rebuild!) after_update_positions end def update_child_positions(_node, #{singular_name}) list = _node['children']['0'] child_positions_changed = false list.sort_by { |k, v| k.to_i}.map { |item| item[1] }.each_with_index do |child, index| child_id = child['id'].split(/#{singular_name}\_?/).reject(&:empty?).first child_#{singular_name} = #{class_name}.where(:id => child_id).first child_positions_changed ||= #{singular_name}.children[index] != child_#{singular_name} if child_positions_changed child_#{singular_name}.move_to_child_of(#{singular_name}) end if child['children'].present? update_child_positions(child, child_#{singular_name}) end end end def after_update_positions head :ok end protected :after_update_positions ), __FILE__, __LINE__ end module_eval %( class << self def pageable? #{options[:paging]} end alias_method :paging?, :pageable? def sortable? #{options[:sortable]} end def searchable? #{options[:searchable]} end end ), __FILE__, __LINE__ end