app/controllers/main.rb in sferik-merb-admin-0.2.7 vs app/controllers/main.rb in sferik-merb-admin-0.2.8

- old
+ new

@@ -1,5 +1,8 @@ +require File.join( File.dirname(__FILE__), '..', '..', 'lib', 'abstract_model' ) +require File.join( File.dirname(__FILE__), '..', '..', 'lib', 'metaid' ) + class MerbAdmin::Main < MerbAdmin::Application before :find_models, :only => ['index'] before :find_model, :exclude => ['index'] before :find_object, :only => ['edit', 'update', 'delete', 'destroy'] @@ -8,133 +11,164 @@ render(:layout => "dashboard") end def list options = {} - filters = params[:filter] || {} - filters.each_pair do |key, value| - if @model.properties[key].primitive.to_s == "TrueClass" - options.merge!(key.to_sym => (value == "true")) - elsif @model.properties[key].primitive.to_s == "Integer" && @model.properties[key].type.respond_to?(:flag_map) - options.merge!(key.to_sym => value.to_sym) - end - end - if params[:query] - condition_statement = [] - conditions = [] - @properties.each do |property| - next unless property.type.to_s == "String" - condition_statement << "#{property.field} LIKE ?" - conditions << "%#{params[:query]}%" - end - conditions.unshift(condition_statement.join(" OR ")) - options.merge!(:conditions => conditions) unless conditions == [""] - end - if params[:sort] - order = "[:#{params[:sort]}.#{params[:sort_reverse] ? 'desc' : 'asc'}]" - options.merge!(:order => eval(order)) - end + merge_filter(options) + merge_query(options) + merge_sort(options) + if !MerbAdmin[:paginate] || params[:all] options = { :limit => 200, }.merge(options) - @objects = @model.all(options).reverse + @objects = @abstract_model.find_all(options).reverse else # monkey patch pagination - @model.class_eval("is_paginated") unless @model.respond_to?(:paginated) + @abstract_model.model.class_eval("is_paginated") unless @abstract_model.model.respond_to?(:paginated) @current_page = (params[:page] || 1).to_i options = { :page => @current_page, :per_page => MerbAdmin[:per_page], }.merge(options) - @page_count, @objects = @model.paginated(options) + @page_count, @objects = @abstract_model.model.paginated(options) + options.delete(:page) + options.delete(:per_page) + options.delete(:offset) + options.delete(:limit) end - options.delete(:page) - options.delete(:per_page) - options.delete(:offset) - options.delete(:limit) - @record_count = @model.count(options) + + @record_count = @abstract_model.count(options) render(:layout => "list") end def new - @object = @model.new + @object = @abstract_model.new render(:layout => "form") end def edit render(:layout => "form") end def create - object = eval("params[:#{@model_name.snake_case}]") || {} - @object = @model.new(object) - if @object.save + object = params[@abstract_model.singular_name] || {} + # Delete fields that are blank + object.each do |key, value| + object.delete(key) if value.blank? + end + associations = @abstract_model.has_many_associations.map{|association| [association, (params[:associations] || {}).delete(association[:name])]} + @object = @abstract_model.new(object) + if @object.save && associations.each{|association, ids| update_has_many_association(association, ids)} if params[:_continue] - redirect(slice_url(:admin_edit, :model_name => @model_name.snake_case, :id => @object.id), :message => {:notice => "#{@model_name} was successfully created"}) + redirect(slice_url(:admin_edit, :model_name => @abstract_model.singular_name, :id => @object.id), :message => {:notice => "#{@abstract_model.pretty_name.capitalize} was successfully created"}) elsif params[:_add_another] - redirect(slice_url(:admin_new, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully created"}) + redirect(slice_url(:admin_new, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name.capitalize} was successfully created"}) else - redirect(slice_url(:admin_list, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully created"}) + redirect(slice_url(:admin_list, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name.capitalize} was successfully created"}) end else - message[:error] = "#{@model_name} failed to be created" + message[:error] = "#{@abstract_model.pretty_name.capitalize} failed to be created" render(:new, :layout => "form") end end def update - object = eval("params[:#{@model_name.snake_case}]") || {} - if @object.update_attributes(object) + object = params[@abstract_model.singular_name] || {} + # Delete fields that are blank + object.each do |key, value| + object.delete(key) if value.blank? + end + associations = @abstract_model.has_many_associations.map{|association| [association, (params[:associations] || {}).delete(association[:name])]} + if @object.update_attributes(object) && associations.each{|association, ids| update_has_many_association(association, ids)} if params[:_continue] - redirect(slice_url(:admin_edit, :model_name => @model_name.snake_case, :id => @object.id), :message => {:notice => "#{@model_name} was successfully updated"}) + redirect(slice_url(:admin_edit, :model_name => @abstract_model.singular_name, :id => @object.id), :message => {:notice => "#{@abstract_model.pretty_name.capitalize} was successfully updated"}) elsif params[:_add_another] - redirect(slice_url(:admin_new, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully updated"}) + redirect(slice_url(:admin_new, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name.capitalize} was successfully updated"}) else - redirect(slice_url(:admin_list, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully updated"}) + redirect(slice_url(:admin_list, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name.capitalize} was successfully updated"}) end else - message[:error] = "#{@model_name} failed to be updated" + message[:error] = "#{@abstract_model.pretty_name.capitalize} failed to be updated" render(:edit, :layout => "form") end end def delete render(:layout => "form") end def destroy if @object.destroy - redirect(slice_url(:admin_list, :model_name => @model_name.snake_case), :message => {:notice => "#{@model_name} was successfully destroyed"}) + redirect(slice_url(:admin_list, :model_name => @abstract_model.singular_name), :message => {:notice => "#{@abstract_model.pretty_name.capitalize} was successfully destroyed"}) else raise BadRequest end end private def find_models - @models = DataMapper::Resource.descendants.to_a.sort{|a, b| a.to_s <=> b.to_s} - # remove DataMapperSessionStore because it's included by default - @models -= [Merb::DataMapperSessionStore] if Merb.const_defined?(:DataMapperSessionStore) + @abstract_models = MerbAdmin::AbstractModel.all end def find_model - @model_name = params[:model_name].camel_case.singularize - begin - @model = eval(@model_name) - rescue StandardError - raise NotFound - end + model_name = params[:model_name].camel_case + @abstract_model = MerbAdmin::AbstractModel.new(model_name) find_properties end def find_properties - @properties = @model.properties.to_a + @properties = @abstract_model.properties end def find_object - @object = @model.get(params[:id]) + @object = @abstract_model.find(params[:id]) raise NotFound unless @object + end + + def merge_filter(options) + return unless params[:filter] + params[:filter].each_pair do |key, value| + @properties.each do |property| + next unless property[:name] == key.to_sym + if property[:type] == :boolean + options.merge!(key.to_sym => (value == "true")) + elsif property[:type] == :integer && property[:flag_map] + options.merge!(key.to_sym => value.to_sym) + end + end + end + end + + def merge_query(options) + return unless params[:query] + condition_statement = [] + conditions = [] + @properties.each do |property| + next unless property[:type] == :string + condition_statement << "#{property[:field]} LIKE ?" + conditions << "%#{params[:query]}%" + end + conditions.unshift(condition_statement.join(" OR ")) + options.merge!(:conditions => conditions) unless conditions == [""] + end + + def merge_sort(options) + return unless params[:sort] + options.merge!(:order => [params[:sort].to_sym.send(params[:sort_reverse] ? :desc : :asc)]) + end + + def update_has_many_association(association, ids) + # Remove all of the associated items + relationship = @object.send(association[:name]) + @object.clear_association(relationship) + # Add all of the objects to the relationship + conditions = {association[:parent_key].first => ids} + model = MerbAdmin::AbstractModel.new(association[:child_model]) + for object in model.find_all(conditions) + relationship << object + end + @object.save end end