{"commit":{"modified":[{"diff":"--- a/app/controllers/rails_admin/application_controller.rb\n+++ b/app/controllers/rails_admin/application_controller.rb\n@@ -8,6 +8,24 @@ module RailsAdmin\n \n helper_method :_current_user\n \n+ def get_model\n+ model_name = to_model_name(params[:model_name])\n+ @abstract_model = RailsAdmin::AbstractModel.new(model_name)\n+ @model_config = RailsAdmin.config(@abstract_model)\n+ not_found if @model_config.excluded?\n+ @properties = @abstract_model.properties\n+ end\n+\n+ def to_model_name(param)\n+ param.split(\"::\").map{|x| x.singularize.camelize}.join(\"::\")\n+ end\n+\n+ def get_object\n+ @object = @abstract_model.get(params[:id])\n+ @model_config.bind(:object, @object)\n+ not_found unless @object\n+ end\n+\n private\n \n def _authenticate!","filename":"app/controllers/rails_admin/application_controller.rb"},{"diff":"--- a/app/controllers/rails_admin/history_controller.rb\n+++ b/app/controllers/rails_admin/history_controller.rb\n@@ -1,12 +1,46 @@\n module RailsAdmin\n class HistoryController < RailsAdmin::ApplicationController\n+ before_filter :get_model, :except => [:list, :slider]\n+ before_filter :get_object, :except => [:list, :slider, :for_model]\n+\n def list\n if params[:ref].nil? or params[:section].nil?\n not_found\n else\n- @history, @current_month = History.get_history_for_month(params[:ref], params[:section])\n+ @history, @current_month = AbstractHistory.history_for_month(params[:ref], params[:section])\n render :template => 'rails_admin/main/history', :layout => false\n end\n end\n+\n+ def slider\n+ ref = params[:ref].to_i\n+\n+ if ref.nil? or ref > 0\n+ not_found\n+ else\n+ render :json => AbstractHistory.history_summaries(ref)\n+ end\n+ end\n+\n+ def for_model\n+ @page_type = @abstract_model.pretty_name.downcase\n+ @page_name = t(\"admin.history.page_name\", :name => @model_config.list.label)\n+ @general = true\n+\n+ @page_count, @history = AbstractHistory.history_for_model @abstract_model, params[:query], params[:sort], params[:sort_reverse], params[:all], params[:page]\n+\n+ render \"show\", :layout => request.xhr? ? false : 'rails_admin/list'\n+ end\n+\n+ def for_object\n+ @page_type = @abstract_model.pretty_name.downcase\n+ @page_name = t(\"admin.history.page_name\", :name => @model_config.bind(:object, @object).list.object_label)\n+ @general = false\n+\n+ @history = AbstractHistory.history_for_object @abstract_model, @object, params[:query], params[:sort], params[:sort_reverse]\n+\n+ render \"show\", :layout => request.xhr? ? false : 'rails_admin/list'\n+ end\n+\n end\n end","filename":"app/controllers/rails_admin/history_controller.rb"},{"diff":"--- a/app/controllers/rails_admin/main_controller.rb\n+++ b/app/controllers/rails_admin/main_controller.rb\n@@ -1,6 +1,6 @@\n module RailsAdmin\n class MainController < RailsAdmin::ApplicationController\n- before_filter :get_model, :except => [:index, :history, :get_history]\n+ before_filter :get_model, :except => [:index]\n before_filter :get_object, :only => [:edit, :update, :delete, :destroy]\n before_filter :get_bulk_objects, :only => [:bulk_delete, :bulk_destroy]\n before_filter :get_attributes, :only => [:create, :update]\n@@ -10,18 +10,20 @@ module RailsAdmin\n @page_name = t(\"admin.dashboard.pagename\")\n @page_type = \"dashboard\"\n \n- @history = History.latest\n+ @history = AbstractHistory.history_latest_summaries\n # history listing with ref = 0 and section = 4\n- @historyListing, @current_month = History.get_history_for_month(0, 4)\n+ @historyListing, @current_month = AbstractHistory.history_for_month(0, 4)\n \n @abstract_models = RailsAdmin::AbstractModel.all\n \n+ @most_recent_changes = {}\n @count = {}\n @max = 0\n @abstract_models.each do |t|\n current_count = t.count\n @max = current_count > @max ? current_count : @max\n @count[t.pretty_name] = current_count\n+ @most_recent_changes[t.pretty_name] = AbstractHistory.most_recent_history(t.pretty_name).last.try(:updated_at)\n end\n \n render :layout => 'rails_admin/dashboard'\n@@ -53,6 +55,7 @@ module RailsAdmin\n @page_type = @abstract_model.pretty_name.downcase\n \n if @object.save && update_all_associations\n+ AbstractHistory.create_history_item(\"Created #{@model_config.bind(:object, @object).list.object_label}\", @object, @abstract_model, _current_user)\n redirect_to_on_success\n else\n render_error\n@@ -76,6 +79,7 @@ module RailsAdmin\n \n @object.send :attributes=, @attributes, false\n if @object.save && update_all_associations\n+ AbstractHistory.create_update_history @abstract_model, @object, @cached_assocations_hash, associations_hash, @modified_assoc, @old_object, _current_user\n redirect_to_on_success\n else\n render_error :edit\n@@ -93,11 +97,11 @@ module RailsAdmin\n @object = @object.destroy\n flash[:notice] = t(\"admin.delete.flash_confirmation\", :name => @model_config.list.label)\n \n- check_history\n+ AbstractHistory.create_history_item(\"Destroyed #{@model_config.bind(:object, @object).list.object_label}\", @object, @abstract_model, _current_user)\n \n redirect_to rails_admin_list_path(:model_name => @abstract_model.to_param)\n end\n- \n+\n def bulk_delete\n @page_name = t(\"admin.actions.delete\").capitalize + \" \" + @model_config.list.label.downcase\n @page_type = @abstract_model.pretty_name.downcase\n@@ -110,82 +114,12 @@ module RailsAdmin\n \n @destroyed_objects.each do |object|\n message = \"Destroyed #{@model_config.bind(:object, object).list.object_label}\"\n- create_history_item(message, object, @abstract_model)\n+ AbstractHistory.create_history_item(message, object, @abstract_model, _current_user)\n end\n \n redirect_to rails_admin_list_path(:model_name => @abstract_model.to_param)\n end\n \n- def history\n- ref = params[:ref].to_i\n-\n- if ref.nil? or ref > 0\n- not_found\n- else\n- current_diff = -5 * ref\n- start_month = (5 + current_diff).month.ago.month\n- start_year = (5 + current_diff).month.ago.year\n- stop_month = (current_diff).month.ago.month\n- stop_year = (current_diff).month.ago.year\n-\n- render :json => History.get_history_for_dates(start_month, stop_month, start_year, stop_year)\n- end\n- end\n-\n- def get_history\n- if params[:ref].nil? or params[:section].nil?\n- not_found\n- else\n- @history, @current_month = History.get_history_for_month(params[:ref], params[:section])\n- render :template => 'rails_admin/main/history'\n- end\n- end\n-\n- def show_history\n- @page_type = @abstract_model.pretty_name.downcase\n- @page_name = t(\"admin.history.page_name\", :name => @model_config.list.label)\n- @general = true\n-\n- options = {}\n- options[:order] = \"created_at DESC\"\n- options[:conditions] = []\n- options[:conditions] << conditions = \"#{History.connection.quote_column_name(:table)} = ?\"\n- options[:conditions] << @abstract_model.pretty_name\n-\n- if params[:id]\n- get_object\n- @page_name = t(\"admin.history.page_name\", :name => @model_config.bind(:object, @object).list.object_label)\n- options[:conditions][0] += \" and #{History.connection.quote_column_name(:item)} = ?\"\n- options[:conditions] << params[:id]\n- @general = false\n- end\n-\n- if params[:query]\n- options[:conditions][0] += \" and (#{History.connection.quote_column_name(:message)} LIKE ? or #{History.connection.quote_column_name(:username)} LIKE ?)\"\n- options[:conditions] << \"%#{params[\"query\"]}%\"\n- options[:conditions] << \"%#{params[\"query\"]}%\"\n- end\n-\n- if params[\"sort\"]\n- options.delete(:order)\n- if params[\"sort_reverse\"] == \"true\"\n- options[:order] = \"#{params[\"sort\"]} desc\"\n- else\n- options[:order] = params[\"sort\"]\n- end\n- end\n-\n- @history = History.find(:all, options)\n-\n- if @general and not params[:all]\n- @current_page = (params[:page] || 1).to_i\n- options.merge!(:page => @current_page, :per_page => 20)\n- @page_count, @history = History.paginated(options)\n- end\n-\n- render :layout => request.xhr? ? false : 'rails_admin/list'\n- end\n-\n def handle_error(e)\n if RailsAdmin::AuthenticationNotConfigured === e\n Rails.logger.error e.message\n@@ -200,20 +134,6 @@ module RailsAdmin\n \n private\n \n- def get_model\n- model_name = to_model_name(params[:model_name])\n- @abstract_model = RailsAdmin::AbstractModel.new(model_name)\n- @model_config = RailsAdmin.config(@abstract_model)\n- not_found if @model_config.excluded?\n- @properties = @abstract_model.properties\n- end\n-\n- def get_object\n- @object = @abstract_model.get(params[:id])\n- @model_config.bind(:object, @object)\n- not_found unless @object\n- end\n- \n def get_bulk_objects\n @bulk_ids = params[:bulk_ids]\n @bulk_objects = @abstract_model.get_bulk(@bulk_ids)\n@@ -317,8 +237,6 @@ module RailsAdmin\n pretty_name = @model_config.update.label\n action = params[:action]\n \n- check_history\n-\n if params[:_add_another]\n flash[:notice] = t(\"admin.flash.successful\", :name => pretty_name, :action => t(\"admin.actions.#{action}d\"))\n redirect_to rails_admin_new_path(:model_name => param)\n@@ -331,82 +249,12 @@ module RailsAdmin\n end\n end\n \n- # TODO: Move this logic to the History class?\n- def check_history\n- action = params[:action]\n- message = []\n-\n- case action\n- when \"create\"\n- message << \"#{action.capitalize}d #{@model_config.bind(:object, @object).list.object_label}\"\n- when \"update\"\n- # determine which fields changed ???\n- changed_property_list = []\n- @properties = @abstract_model.properties.reject{|property| RailsAdmin::History::IGNORED_ATTRS.include?(property[:name])}\n-\n- @properties.each do |property|\n- property_name = property[:name].to_param\n- if @old_object.send(property_name) != @object.send(property_name)\n- changed_property_list << property_name\n- end\n- end\n-\n- @abstract_model.associations.each do |t|\n- assoc = changed_property_list.index(t[:child_key].to_param)\n- if assoc\n- changed_property_list[assoc] = \"associated #{t[:pretty_name]}\"\n- end\n- end\n-\n- # Determine if any associations were added or removed\n- associations_hash.each do |key, current|\n- removed_ids = (@cached_assocations_hash[key] - current).map{|m| '#' + m.to_s}\n- added_ids = (current - @cached_assocations_hash[key]).map{|m| '#' + m.to_s}\n- if removed_ids.any?\n- message << \"Removed #{key.to_s.capitalize} #{removed_ids.join(', ')} associations\"\n- end\n- if added_ids.any?\n- message << \"Added #{key.to_s.capitalize} #{added_ids.join(', ')} associations\"\n- end\n- end\n-\n- @modified_assoc.uniq.each do |t|\n- changed_property_list << \"associated #{t}\"\n- end\n-\n- if not changed_property_list.empty?\n- message << \"Changed #{changed_property_list.join(\", \")}\"\n- end\n- when \"destroy\"\n- message << \"Destroyed #{@model_config.bind(:object, @object).list.object_label}\"\n- end\n-\n- create_history_item(message, @object, @abstract_model) unless message.empty?\n- end\n-\n- def create_history_item(message, object, abstract_model)\n- message = message.join(', ') if message.is_a? Array\n- date = Time.now\n- History.create(\n- :message => message,\n- :item => object.id,\n- :table => abstract_model.pretty_name,\n- :username => _current_user ? _current_user.email : \"\",\n- :month => date.month,\n- :year => date.year\n- )\n- end\n-\n def render_error whereto = :new\n action = params[:action]\n flash.now[:error] = t(\"admin.flash.error\", :name => @model_config.update.label, :action => t(\"admin.actions.#{action}d\"))\n render whereto, :layout => 'rails_admin/form'\n end\n \n- def to_model_name(param)\n- param.split(\"::\").map{|x| x.singularize.camelize}.join(\"::\")\n- end\n-\n def check_for_cancel\n if params[:_continue]\n flash[:notice] = t(\"admin.flash.noaction\")","filename":"app/controllers/rails_admin/main_controller.rb"},{"diff":"--- a/app/helpers/rails_admin/application_helper.rb\n+++ b/app/helpers/rails_admin/application_helper.rb\n@@ -7,5 +7,109 @@ module RailsAdmin\n return t.message.downcase\n end\n end\n+\n+ # Given a page count and the current page, we generate a set of pagination\n+ # links.\n+ #\n+ # * We use an inner and outer window into a list of links. For a set of\n+ # 20 pages with the current page being 10:\n+ # outer_window:\n+ # 1 2 ..... 19 20\n+ # inner_window\n+ # 5 6 7 8 9 10 11 12 13 14\n+ #\n+ # This is totally adjustable, or can be turned off by giving the\n+ # :inner_window setting a value of nil.\n+ #\n+ # * Options\n+ # :left_cut_label => text_for_cut::\n+ # Used when the page numbers need to be cut off to prevent the set of\n+ # pagination links from being too long.\n+ # Defaults to '…'\n+ # :right_cut_label => text_for_cut::\n+ # Same as :left_cut_label but for the right side of numbers.\n+ # Defaults to '…'\n+ # :outer_window => number_of_pages::\n+ # Sets the number of pages to include in the outer 'window'\n+ # Defaults to 2\n+ # :inner_window => number_of_pages::\n+ # Sets the number of pags to include in the inner 'window'\n+ # Defaults to 7\n+ # :page_param => name_of_page_paramiter\n+ # Sets the name of the paramiter the paginator uses to return what\n+ # page is being requested.\n+ # Defaults to 'page'\n+ # :url => url_for_links\n+ # Provides the base url to use in the page navigation links.\n+ # Defaults to ''\n+ def paginate(current_page, page_count, options = {})\n+ options[:left_cut_label] ||= '…'\n+ options[:right_cut_label] ||= '…'\n+ options[:outer_window] ||= 2\n+ options[:inner_window] ||= 7\n+ options[:page_param] ||= 'page'\n+ options[:url] ||= \"\"\n+\n+ url = options.delete(:url)\n+ url = url.to_a.collect{|x| x.join(\"=\")}.join(\"&\")\n+\n+ url += (url.include?('=') ? '&' : '') + options[:page_param]\n+ url = \"?\"+url\n+\n+ pages = {\n+ :all => (1..page_count).to_a,\n+ :left => [],\n+ :center => [],\n+ :right => []\n+ }\n+\n+ # Only worry about using our 'windows' if the page count is less then\n+ # our windows combined.\n+ if options[:inner_window].nil? || ((options[:outer_window] * 2) + options[:inner_window] + 2) >= page_count\n+ pages[:center] = pages[:all]\n+ else\n+ pages[:left] = pages[:all][0, options[:outer_window]]\n+ pages[:right] = pages[:all][page_count - options[:outer_window], options[:outer_window]]\n+ pages[:center] = case current_page\n+ # allow the inner 'window' to shift to right when close to the left edge\n+ # Ex: 1 2 [3] 4 5 6 7 8 9 ... 20\n+ when -infinity .. (options[:inner_window] / 2) + 3\n+ pages[:all][options[:outer_window], options[:inner_window]] +\n+ [options[:right_cut_label]]\n+ # allow the inner 'window' to shift left when close to the right edge\n+ # Ex: 1 2 ... 12 13 14 15 16 [17] 18 19 20\n+ when (page_count - (options[:inner_window] / 2.0).ceil) - 1 .. infinity\n+ [options[:left_cut_label]] +\n+ pages[:all][page_count - options[:inner_window] - options[:outer_window], options[:inner_window]]\n+ # Display the unshifed window\n+ # ex: 1 2 ... 5 6 7 [8] 9 10 11 ... 19 20\n+ else\n+ [options[:left_cut_label]] +\n+ pages[:all][current_page - (options[:inner_window] / 2) - 1, options[:inner_window]] +\n+ [options[:right_cut_label]]\n+ end\n+ end\n+\n+ b = []\n+\n+ [pages[:left], pages[:center], pages[:right]].each do |p|\n+ p.each do |page_number|\n+\n+ case page_number\n+ when String\n+ b << page_number\n+ when current_page\n+ b << Builder::XmlMarkup.new.span(page_number, :class => \"this-page\")\n+ when page_count\n+ b << Builder::XmlMarkup.new.a(page_number, :class => \"end\", :href => \"#{url}=#{page_number}\")\n+ else\n+ b << Builder::XmlMarkup.new.a(page_number, :href => \"#{url}=#{page_number}\")\n+ end\n+ end\n+ end\n+\n+ b.join(\" \")\n+ end\n+\n end\n end","filename":"app/helpers/rails_admin/application_helper.rb"},{"diff":"--- a/app/helpers/rails_admin/main_helper.rb\n+++ b/app/helpers/rails_admin/main_helper.rb\n@@ -21,109 +21,6 @@ module RailsAdmin\n return style, other, selected_set\n end\n \n- # Given a page count and the current page, we generate a set of pagination\n- # links.\n- #\n- # * We use an inner and outer window into a list of links. For a set of\n- # 20 pages with the current page being 10:\n- # outer_window:\n- # 1 2 ..... 19 20\n- # inner_window\n- # 5 6 7 8 9 10 11 12 13 14\n- #\n- # This is totally adjustable, or can be turned off by giving the\n- # :inner_window setting a value of nil.\n- #\n- # * Options\n- # :left_cut_label => text_for_cut::\n- # Used when the page numbers need to be cut off to prevent the set of\n- # pagination links from being too long.\n- # Defaults to '…'\n- # :right_cut_label => text_for_cut::\n- # Same as :left_cut_label but for the right side of numbers.\n- # Defaults to '…'\n- # :outer_window => number_of_pages::\n- # Sets the number of pages to include in the outer 'window'\n- # Defaults to 2\n- # :inner_window => number_of_pages::\n- # Sets the number of pags to include in the inner 'window'\n- # Defaults to 7\n- # :page_param => name_of_page_paramiter\n- # Sets the name of the paramiter the paginator uses to return what\n- # page is being requested.\n- # Defaults to 'page'\n- # :url => url_for_links\n- # Provides the base url to use in the page navigation links.\n- # Defaults to ''\n- def paginate(current_page, page_count, options = {})\n- options[:left_cut_label] ||= '…'\n- options[:right_cut_label] ||= '…'\n- options[:outer_window] ||= 2\n- options[:inner_window] ||= 7\n- options[:page_param] ||= 'page'\n- options[:url] ||= \"\"\n-\n- url = options.delete(:url)\n- url = url.to_a.collect{|x| x.join(\"=\")}.join(\"&\")\n-\n- url += (url.include?('=') ? '&' : '') + options[:page_param]\n- url = \"?\"+url\n-\n- pages = {\n- :all => (1..page_count).to_a,\n- :left => [],\n- :center => [],\n- :right => []\n- }\n-\n- # Only worry about using our 'windows' if the page count is less then\n- # our windows combined.\n- if options[:inner_window].nil? || ((options[:outer_window] * 2) + options[:inner_window] + 2) >= page_count\n- pages[:center] = pages[:all]\n- else\n- pages[:left] = pages[:all][0, options[:outer_window]]\n- pages[:right] = pages[:all][page_count - options[:outer_window], options[:outer_window]]\n- pages[:center] = case current_page\n- # allow the inner 'window' to shift to right when close to the left edge\n- # Ex: 1 2 [3] 4 5 6 7 8 9 ... 20\n- when -infinity .. (options[:inner_window] / 2) + 3\n- pages[:all][options[:outer_window], options[:inner_window]] +\n- [options[:right_cut_label]]\n- # allow the inner 'window' to shift left when close to the right edge\n- # Ex: 1 2 ... 12 13 14 15 16 [17] 18 19 20\n- when (page_count - (options[:inner_window] / 2.0).ceil) - 1 .. infinity\n- [options[:left_cut_label]] +\n- pages[:all][page_count - options[:inner_window] - options[:outer_window], options[:inner_window]]\n- # Display the unshifed window\n- # ex: 1 2 ... 5 6 7 [8] 9 10 11 ... 19 20\n- else\n- [options[:left_cut_label]] +\n- pages[:all][current_page - (options[:inner_window] / 2) - 1, options[:inner_window]] +\n- [options[:right_cut_label]]\n- end\n- end\n-\n- b = []\n-\n- [pages[:left], pages[:center], pages[:right]].each do |p|\n- p.each do |page_number|\n-\n- case page_number\n- when String\n- b << page_number\n- when current_page\n- b << Builder::XmlMarkup.new.span(page_number, :class => \"this-page\")\n- when page_count\n- b << Builder::XmlMarkup.new.a(page_number, :class => \"end\", :href => \"#{url}=#{page_number}\")\n- else\n- b << Builder::XmlMarkup.new.a(page_number, :href => \"#{url}=#{page_number}\")\n- end\n- end\n- end\n-\n- b.join(\" \")\n- end\n-\n private\n \n def infinity","filename":"app/helpers/rails_admin/main_helper.rb"},{"diff":"--- a/app/models/rails_admin/blank_history.rb\n+++ b/app/models/rails_admin/blank_history.rb\n@@ -6,5 +6,11 @@ module RailsAdmin\n @month = month\n @year = year\n end\n+\n+ # Make BlankHistory look like History when it gets JSON-serialized.\n+ def to_hash(*a)\n+ {\"history\" => {\"number\" => @number, \"month\" => @month, \"year\" => @year}}\n+ end\n+\n end\n end","filename":"app/models/rails_admin/blank_history.rb"},{"diff":"--- a/app/models/rails_admin/history.rb\n+++ b/app/models/rails_admin/history.rb\n@@ -7,31 +7,6 @@ module RailsAdmin\n where(\"#{retrieve_connection.quote_column_name(:table)} = ?\", table).order(\"updated_at\")\n }\n \n- def self.paginated(options = {})\n- page = options.delete(:page) || 1\n- per_page = options.delete(:per_page) || RailsAdmin[:per_page]\n-\n- page_count = (count(options).to_f / per_page).ceil\n-\n- options.merge!({\n- :limit => per_page,\n- :offset => (page - 1) * per_page\n- })\n-\n- [page_count, all(options)]\n- end\n-\n- def self.latest\n- mstart = 5.month.ago.month\n- mstop = Time.now.month\n-\n- ystop = Time.now.year\n- ystart = 5.month.ago.year\n-\n- self.get_history_for_dates(mstart, mstop, ystart, ystop)\n- end\n-\n-\n def self.get_history_for_dates(mstart, mstop, ystart, ystop)\n sql_in = \"\"\n if mstart > mstop\n@@ -65,14 +40,5 @@ module RailsAdmin\n end\n end\n end\n-\n- def self.get_history_for_month(ref, section)\n- current_ref = -5 * ref.to_i\n- current_diff = current_ref + 5 - (section.to_i + 1)\n-\n- current_month = current_diff.month.ago\n-\n- return History.find(:all, :conditions => [\"month = ? and year = ?\", current_month.month, current_month.year]), current_month\n- end\n end\n end","filename":"app/models/rails_admin/history.rb"},{"diff":"--- a/app/views/rails_admin/main/edit.html.erb\n+++ b/app/views/rails_admin/main/edit.html.erb\n@@ -4,7 +4,7 @@\n