From cdd6d2c4706dbc6a6b37054df17126a5559c5521 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 16 Oct 2014 19:57:16 +0200 Subject: [PATCH 0001/3836] support for :title on form (close #3150) --- lib/active_admin/views/pages/form.rb | 6 +++++- spec/unit/views/pages/form_spec.rb | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/views/pages/form.rb b/lib/active_admin/views/pages/form.rb index 7362ebfcc9f..69b6172f809 100644 --- a/lib/active_admin/views/pages/form.rb +++ b/lib/active_admin/views/pages/form.rb @@ -5,8 +5,12 @@ module Pages class Form < Base def title - assigns[:page_title] || I18n.t("active_admin.#{params[:action]}_model", + if form_presenter[:title] + render_or_call_method_or_proc_on(resource, form_presenter[:title]) + else + assigns[:page_title] || I18n.t("active_admin.#{params[:action]}_model", model: active_admin_config.resource_label) + end end def form_presenter diff --git a/spec/unit/views/pages/form_spec.rb b/spec/unit/views/pages/form_spec.rb index 55482581ae0..19773c0144b 100644 --- a/spec/unit/views/pages/form_spec.rb +++ b/spec/unit/views/pages/form_spec.rb @@ -16,6 +16,15 @@ OpenStruct.new(params: params, helpers: helpers, assigns: {}) end + context "when :title is set" do + it "should show the set page title" do + page = ActiveAdmin::Views::Pages::Form.new(arbre_context) + expect(page).to receive(:resource) + expect(page).to receive(:form_presenter).twice.and_return({ title: "My Page Title" }) + expect(page.title).to eq "My Page Title" + end + end + context "when page_title is assigned" do it "should show the set page title" do arbre_context.assigns[:page_title] = "My Page Title" From e3908e5f308e142905024d1e583eec7e711bfb03 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 3 May 2015 20:09:22 -0500 Subject: [PATCH 0002/3836] make deprecations cause the test suite to fail --- features/support/env.rb | 9 ++++++++- spec/rails_helper.rb | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/features/support/env.rb b/features/support/env.rb index 8ad400dcebd..93c9b0cca81 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -106,7 +106,6 @@ end Before do - begin # We are caching classes, but need to manually clear references to # the controllers. If they aren't clear, the router stores references @@ -121,6 +120,14 @@ end end +# Force deprecations to raise an exception. +# This would set `behavior = :raise`, but that wasn't added until Rails 4. +ActiveSupport::Deprecation.behavior = -> message, callstack do + e = StandardError.new message + e.set_backtrace callstack + raise e +end + # improve the performance of the specs suite by not logging anything # see http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/ Rails.logger.level = 4 diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 2a9367dbadf..0e66ba9c85d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -143,11 +143,18 @@ def with_translation(translation) c.include Devise::TestHelpers, type: :controller end +# Force deprecations to raise an exception. +# This would set `behavior = :raise`, but that wasn't added until Rails 4. +ActiveSupport::Deprecation.behavior = -> message, callstack do + e = StandardError.new message + e.set_backtrace callstack + raise e +end + # improve the performance of the specs suite by not logging anything # see http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/ Rails.logger.level = 4 - # Improves performance by forcing the garbage collector to run less often. unless ENV['DEFER_GC'] == '0' || ENV['DEFER_GC'] == 'false' require 'support/deferred_garbage_collection' From 714b092105c918c1147659c69c3d18b8447a3549 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 3 May 2015 20:19:48 -0500 Subject: [PATCH 0003/3836] use `columns_hash` to get around deprecation warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we couldn’t use `type_for_column` since: - it’s not intended as a public method and - it would return a null object if the column had the default value (nil) for example: ``` expected: "No" got: "" (compared using ==) (RSpec::Expectations::ExpectationNotMetError) ./features/step_definitions/table_steps.rb:96:in `assert_cells_match' ./features/step_definitions/table_steps.rb:79:in `block (2 levels) in assert_tables_match' ./features/step_definitions/table_steps.rb:75:in `each_index' ./features/step_definitions/table_steps.rb:75:in `block in assert_tables_match' ./features/step_definitions/table_steps.rb:74:in `each_index' ./features/step_definitions/table_steps.rb:74:in `assert_tables_match' ./features/step_definitions/table_steps.rb:115:in `/^I should see the "([^"]*)" table:$/' features/index/index_as_table.feature:252:in `Then I should see the "index_table_posts" table:' Failing Scenarios: cucumber features/index/index_as_table.feature:244 # Scenario: Sorting ``` --- lib/active_admin/views/components/table_for.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/active_admin/views/components/table_for.rb b/lib/active_admin/views/components/table_for.rb index 23ff9d323df..6eaaaf9c760 100644 --- a/lib/active_admin/views/components/table_for.rb +++ b/lib/active_admin/views/components/table_for.rb @@ -116,10 +116,8 @@ def render_data(data, item) end def is_boolean?(data, item) - if item.respond_to? :has_attribute? - item.has_attribute?(data) && - item.column_for_attribute(data) && - item.column_for_attribute(data).type == :boolean + if item.class.respond_to? :columns_hash + column = item.class.columns_hash[data.to_s] and column.type == :boolean end end From 87e5828b86ee5ef733071827bba6026087b5acda Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 11 Oct 2015 10:12:38 -0500 Subject: [PATCH 0004/3836] ensure that boolean fields are decorated --- features/decorators.feature | 2 ++ features/step_definitions/factory_steps.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/features/decorators.feature b/features/decorators.feature index 8d00c98ea9a..268ff231c6d 100644 --- a/features/decorators.feature +++ b/features/decorators.feature @@ -17,12 +17,14 @@ Feature: Decorators column(:id) column(:title) column(:decorator_method) + column(:starred) end end """ When I am on the index page for posts Then I should see "A method only available on the decorator" And I should see "A very unique post" + And I should see "No" Scenario: Show page with decorator Given a configuration of: diff --git a/features/step_definitions/factory_steps.rb b/features/step_definitions/factory_steps.rb index 29523634b6f..5375eabe705 100644 --- a/features/step_definitions/factory_steps.rb +++ b/features/step_definitions/factory_steps.rb @@ -5,9 +5,9 @@ def create_user(name, type = 'User') Given /^(a|\d+)( published)?( unstarred|starred)? posts?(?: with the title "([^"]*)")?(?: and body "([^"]*)")?(?: written by "([^"]*)")?(?: in category "([^"]*)")? exists?$/ do |count, published, starred, title, body, user, category_name| count = count == 'a' ? 1 : count.to_i - published = Time.now if published + published = Time.now if published starred = starred == " starred" if starred - author = create_user(user) if user + author = create_user(user) if user category = Category.where(name: category_name).first_or_create if category_name title ||= "Hello World %i" count.times do |i| From 9a1237c5147b4b3da007fbe19b63d0fcc38a10fb Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 11 Oct 2015 13:34:17 -0500 Subject: [PATCH 0005/3836] #3930 forces deprecation warnings to cause test failures, so we're forced to fix them. This is one deprecation: >DEPRECATION WARNING: Using ActiveRecord's `find` on a CollectionDecorator is deprecated. Call `find` on a model, and then decorate the result. (called from block in add_default_batch_action at lib/active_admin/batch_actions/resource_extension.rb:73) (StandardError) This issue was introduced by #3775, which started decorating collections for batch actions. The Draper ticket that resulted in the deprecation is: https://github.com/drapergem/draper/issues/509. The simple solution would be to no longer decorate the batch action collections, which is what this commit does. --- lib/active_admin/batch_actions/controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/active_admin/batch_actions/controller.rb b/lib/active_admin/batch_actions/controller.rb index edf9fa2d985..03a13bd8a99 100644 --- a/lib/active_admin/batch_actions/controller.rb +++ b/lib/active_admin/batch_actions/controller.rb @@ -30,7 +30,6 @@ def current_batch_action :filtering, :scoping, :includes, - :collection_decorator ].freeze def batch_action_collection(only = COLLECTION_APPLIES) From e4aa309eebe39e30f5f3a6355e86956a32e110df Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 11 Oct 2015 13:35:24 -0500 Subject: [PATCH 0006/3836] simplify `collection_applies` --- lib/active_admin/resource_controller/data_access.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index e4e55e61db4..b48f3d6ece8 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -275,12 +275,10 @@ def apply_pagination(chain) end def collection_applies(options = {}) - only = Array(options.fetch(:only, COLLECTION_APPLIES)) + only = Array(options.fetch(:only, COLLECTION_APPLIES)) except = Array(options.fetch(:except, [])) - - # see #4074 for code reasons - COLLECTION_APPLIES.select { |applier| only.include? applier } - .reject { |applier| except.include? applier } + + COLLECTION_APPLIES & only - except end def per_page From 927b6451d790009107b25742a3ec836094eff5d4 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Mon, 2 Nov 2015 11:03:38 -0600 Subject: [PATCH 0007/3836] Add Contributor Covenant as our code of conduct The purpose of adopting this code of conduct is to signal to potential contributors that this is a project where they won't be abused or attacked in any way. It also signals to everyone else that such behavior will not be tolerated. This COC is copied from http://contributor-covenant.org/ I'll leave this PR open for a week, in the case that people have concerns with the wording. --- CODE_OF_CONDUCT.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..01b8644f13a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,22 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic addresses, without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. + +This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) From 471aa34c76dad806f12a2f5903ff21f8440fd561 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 19 Nov 2015 18:52:19 -0600 Subject: [PATCH 0008/3836] Don't stream CSV in development This enables any exceptions to bubble up, instead of waiting until the request times out before sending back any data. This also lets you use in-browser debuggers, like better_errors. --- lib/active_admin/application.rb | 3 +++ lib/active_admin/csv_builder.rb | 10 ++++++---- lib/active_admin/resource_controller/streaming.rb | 7 ++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/active_admin/application.rb b/lib/active_admin/application.rb index 54200e82cff..544f92a4113 100644 --- a/lib/active_admin/application.rb +++ b/lib/active_admin/application.rb @@ -125,6 +125,9 @@ def initialize :email, :to_s ] + # To make debugging easier, by default don't stream in development + setting :disable_streaming_in, ['development'] + # == Deprecated Settings def allow_comments=(*) diff --git a/lib/active_admin/csv_builder.rb b/lib/active_admin/csv_builder.rb index a47aa4616a1..e5940e6ca7d 100644 --- a/lib/active_admin/csv_builder.rb +++ b/lib/active_admin/csv_builder.rb @@ -39,17 +39,17 @@ def column(name, options={}, &block) @columns << Column.new(name, @resource, column_transitive_options.merge(options), block) end - def build(controller, receiver) + def build(controller, csv) @collection = controller.send(:find_collection, except: :pagination) options = ActiveAdmin.application.csv_options.merge self.options columns = exec_columns controller.view_context if byte_order_mark = options.delete(:byte_order_mark) - receiver << byte_order_mark + csv << byte_order_mark end if options.delete(:column_names) { true } - receiver << CSV.generate_line( + csv << CSV.generate_line( columns.map { |c| encode c.name, options }, options.except(:encoding_options)) end @@ -57,11 +57,13 @@ def build(controller, receiver) (1..paginated_collection.total_pages).each do |page_no| paginated_collection(page_no).each do |resource| resource = controller.send :apply_decorator, resource - receiver << CSV.generate_line( + csv << CSV.generate_line( build_row(resource, columns, options), options.except(:encoding_options)) end end + + csv end def exec_columns(view_context = nil) diff --git a/lib/active_admin/resource_controller/streaming.rb b/lib/active_admin/resource_controller/streaming.rb index d680a7fb7e0..bcfc9150308 100644 --- a/lib/active_admin/resource_controller/streaming.rb +++ b/lib/active_admin/resource_controller/streaming.rb @@ -20,7 +20,12 @@ def index def stream_resource(&block) headers['X-Accel-Buffering'] = 'no' headers['Cache-Control'] = 'no-cache' - self.response_body = Enumerator.new &block + + if ActiveAdmin.application.disable_streaming_in.include? Rails.env + self.response_body = block[''] + else + self.response_body = Enumerator.new &block + end end def csv_filename From 69f213476129baf55a615d40456fc752bfdfe814 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 19 Nov 2015 19:03:13 -0600 Subject: [PATCH 0009/3836] change code style in CSV builder --- lib/active_admin/csv_builder.rb | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/active_admin/csv_builder.rb b/lib/active_admin/csv_builder.rb index e5940e6ca7d..5a391dd78b2 100644 --- a/lib/active_admin/csv_builder.rb +++ b/lib/active_admin/csv_builder.rb @@ -40,26 +40,23 @@ def column(name, options={}, &block) end def build(controller, csv) - @collection = controller.send(:find_collection, except: :pagination) - options = ActiveAdmin.application.csv_options.merge self.options - columns = exec_columns controller.view_context + @collection = controller.send :find_collection, except: :pagination + columns = exec_columns controller.view_context + options = ActiveAdmin.application.csv_options.merge self.options + bom = options.delete :byte_order_mark + column_names = options.delete(:column_names) { true } + csv_options = options.except :encoding_options - if byte_order_mark = options.delete(:byte_order_mark) - csv << byte_order_mark - end + csv << bom if bom - if options.delete(:column_names) { true } - csv << CSV.generate_line( - columns.map { |c| encode c.name, options }, - options.except(:encoding_options)) + if column_names + csv << CSV.generate_line(columns.map{ |c| encode c.name, options }, csv_options) end - (1..paginated_collection.total_pages).each do |page_no| - paginated_collection(page_no).each do |resource| + (1..paginated_collection.total_pages).each do |page| + paginated_collection(page).each do |resource| resource = controller.send :apply_decorator, resource - csv << CSV.generate_line( - build_row(resource, columns, options), - options.except(:encoding_options)) + csv << CSV.generate_line(build_row(resource, columns, options), csv_options) end end From ed8c62d6f3c87cc7762c87d49bac4ab136471b18 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 19 Nov 2015 19:08:38 -0600 Subject: [PATCH 0010/3836] change Travis config order so local dev works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit local dev uses the last Rails version in the list. Until #4177 is resolved, Rails 5 / master can’t be the default --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4e7a7bcc028..8150b60eba3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ env: matrix: - RAILS=3.2.22 - RAILS=4.1.13 - - RAILS=4.2.4 - RAILS=master + - RAILS=4.2.4 global: - JRUBY_OPTS="-J-Xmx1024m --debug" matrix: From 2f96673d2cc2c083bcf72ce61465536e6b40bd27 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Fri, 20 Nov 2015 10:30:24 -0600 Subject: [PATCH 0011/3836] add documentation & changelog entries for CSV streaming --- CHANGELOG.md | 2 ++ docs/4-csv-format.md | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2681ffd0b75..63c7102c1fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ #### Minor +* Stream CSV downloads as they're generated [#3038][] by [@craigmcnamara][] + * Disable streaming in development for easier debugging [#3535][] by [@seanlinsley][] * Improved code reloading [#3783][] by [@chancancode][] * Do not auto link to inaccessible actions [#3686][] by [@pranas][] * Allow to enable comments on per-resource basis [#3695][] by [@pranas][] diff --git a/docs/4-csv-format.md b/docs/4-csv-format.md index 2a03740dc14..6b3a69ed26c 100644 --- a/docs/4-csv-format.md +++ b/docs/4-csv-format.md @@ -38,3 +38,21 @@ config.csv_options = { col_sep: ';' } # Force the use of quotes config.csv_options = { force_quotes: true } ``` + +## Streaming + +By default Active Admin streams the CSV response to your browser as it's generated. +This is good because it prevents request timeouts, for example the infamous H12 +error on Heroku. + +However if an exception occurs while generating the CSV, the request will eventually +time out, with the last line containing the exception message. CSV streaming is +disabled in development to help debug these exceptions. That lets you use tools like +better_errors and web-console to debug the issue. If you want to customize the +environments where CSV streaming is disabled, you can change this setting: + +```ruby +# config/initializers/active_admin.rb + +config.disable_streaming_in = ['development', 'staging'] +``` From 01ad42f4a12a639f31b22fe7f481d497927d772e Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 22 Nov 2015 17:46:40 -0600 Subject: [PATCH 0012/3836] separate application.js into separate initializers closes #3588, closes #3605 --- .../active_admin/application.js.coffee | 37 ------------------- .../javascripts/active_admin/base.js.coffee | 2 +- .../initializers/batch_actions.js.coffee | 7 ++++ .../initializers/datepicker.js.coffee | 10 +++++ .../initializers/filters.js.coffee | 15 ++++++++ .../active_admin/initializers/tabs.js.coffee | 3 ++ 6 files changed, 36 insertions(+), 38 deletions(-) delete mode 100644 app/assets/javascripts/active_admin/application.js.coffee create mode 100644 app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee create mode 100644 app/assets/javascripts/active_admin/initializers/datepicker.js.coffee create mode 100644 app/assets/javascripts/active_admin/initializers/filters.js.coffee create mode 100644 app/assets/javascripts/active_admin/initializers/tabs.js.coffee diff --git a/app/assets/javascripts/active_admin/application.js.coffee b/app/assets/javascripts/active_admin/application.js.coffee deleted file mode 100644 index 8d572cecea2..00000000000 --- a/app/assets/javascripts/active_admin/application.js.coffee +++ /dev/null @@ -1,37 +0,0 @@ -# Initializers -$(document).on 'ready page:load', -> - # jQuery datepickers (also evaluates dynamically added HTML) - $(document).on 'focus', 'input.datepicker:not(.hasDatepicker)', -> - $input = $(@) - - # Only applying datepicker to compatible browsers - return if $input[0].type is 'date' - - defaults = dateFormat: 'yy-mm-dd' - options = $input.data 'datepicker-options' - $input.datepicker $.extend(defaults, options) - - # Clear Filters button - $('.clear_filters_btn').click -> - params = window.location.search.slice(1).split('&') - regex = /^(q\[|q%5B|q%5b|page|commit)/ - window.location.search = (param for param in params when not param.match(regex)).join('&') - - # Filter form: don't send any inputs that are empty - $('.filter_form').submit -> - $(@).find(':input').filter(-> @value is '').prop 'disabled', true - - # Filter form: for filters that let you choose the query method from - # a dropdown, apply that choice to the filter input field. - $('.filter_form_field.select_and_search select').change -> - $(@).siblings('input').prop name: "q[#{@value}]" - - # Tab navigation - $('#active_admin_content .tabs').tabs() - - # In order for index scopes to overflow properly onto the next line, we have - # to manually set its width based on the width of the batch action button. - if (batch_actions_selector = $('.table_tools .batch_actions_selector')).length - batch_actions_selector.next().css - width: "calc(100% - 10px - #{batch_actions_selector.outerWidth()}px)" - 'float': 'right' diff --git a/app/assets/javascripts/active_admin/base.js.coffee b/app/assets/javascripts/active_admin/base.js.coffee index bf421a2a8d2..6f184cafcc5 100644 --- a/app/assets/javascripts/active_admin/base.js.coffee +++ b/app/assets/javascripts/active_admin/base.js.coffee @@ -4,6 +4,6 @@ #= require_self #= require_tree ./lib #= require_tree ./ext -#= require ./application +#= require_tree ./initializers window.ActiveAdmin = {} diff --git a/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee b/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee new file mode 100644 index 00000000000..acda259a692 --- /dev/null +++ b/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee @@ -0,0 +1,7 @@ +$(document).on 'ready page:load', -> + # In order for index scopes to overflow properly onto the next line, we have + # to manually set its width based on the width of the batch action button. + if (batch_actions_selector = $('.table_tools .batch_actions_selector')).length + batch_actions_selector.next().css + width: "calc(100% - 10px - #{batch_actions_selector.outerWidth()}px)" + 'float': 'right' diff --git a/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee b/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee new file mode 100644 index 00000000000..ef69d98e953 --- /dev/null +++ b/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee @@ -0,0 +1,10 @@ +$(document).on 'ready page:load', -> + $(document).on 'focus', 'input.datepicker:not(.hasDatepicker)', -> + input = $(@) + + # Only create datepickers in compatible browsers + return if input[0].type is 'date' + + defaults = dateFormat: 'yy-mm-dd' + options = input.data 'datepicker-options' + input.datepicker $.extend(defaults, options) diff --git a/app/assets/javascripts/active_admin/initializers/filters.js.coffee b/app/assets/javascripts/active_admin/initializers/filters.js.coffee new file mode 100644 index 00000000000..992da9d46e6 --- /dev/null +++ b/app/assets/javascripts/active_admin/initializers/filters.js.coffee @@ -0,0 +1,15 @@ +$(document).on 'ready page:load', -> + # Clear Filters button + $('.clear_filters_btn').click -> + params = window.location.search.slice(1).split('&') + regex = /^(q\[|q%5B|q%5b|page|commit)/ + window.location.search = (param for param in params when not param.match(regex)).join('&') + + # Filter form: don't send any inputs that are empty + $('.filter_form').submit -> + $(@).find(':input').filter(-> @value is '').prop 'disabled', true + + # Filter form: for filters that let you choose the query method from + # a dropdown, apply that choice to the filter input field. + $('.filter_form_field.select_and_search select').change -> + $(@).siblings('input').prop name: "q[#{@value}]" diff --git a/app/assets/javascripts/active_admin/initializers/tabs.js.coffee b/app/assets/javascripts/active_admin/initializers/tabs.js.coffee new file mode 100644 index 00000000000..b469cca3d69 --- /dev/null +++ b/app/assets/javascripts/active_admin/initializers/tabs.js.coffee @@ -0,0 +1,3 @@ +$(document).on 'ready page:load', -> + # Tab navigation + $('#active_admin_content .tabs').tabs() From fe435e11762b942715a422284992fce705e0761d Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 22 Nov 2015 20:04:54 -0600 Subject: [PATCH 0013/3836] run Travis against Rails 3.2 and Ruby 2 closes #3715 --- .travis.yml | 4 ---- Gemfile | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8150b60eba3..f3a857a26e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,10 +25,6 @@ env: matrix: fast_finish: true exclude: - - rvm: 2.2.3 - env: RAILS=3.2.22 - - rvm: jruby-9.0.0.0 - env: RAILS=3.2.22 - rvm: 1.9 env: RAILS=master allow_failures: diff --git a/Gemfile b/Gemfile index b6b56851419..84c9ac5fd85 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,8 @@ gem 'rails', rails_version == 'master' ? {github: 'rails/rails'} : rails_version gem 'jquery-ui-rails', rails_version[0] == '3' ? '~> 4.0' : '~> 5.0' +gem 'test-unit', '~> 3.0' if rails_version[0] == '3' + if rails_version == 'master' gem 'arel', github: 'rails/arel' gem 'sprockets', github: 'rails/sprockets' From f8ef8ca7f9ce6dc70a4761d6269477f0dff448ec Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 22 Nov 2015 20:18:07 -0600 Subject: [PATCH 0014/3836] #3630: update resource scoping documentation --- docs/2-resource-customization.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index daa4a2d2374..8464b3a03b0 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -297,6 +297,9 @@ end ## Customizing resource retrieval +Our controllers are built on [Inherited Resources](https://github.com/josevalim/inherited_resources), +so you can use [all of its features](https://github.com/josevalim/inherited_resources#overwriting-defaults). + If you need to customize the collection properties, you can overwrite the `scoped_collection` method. ```ruby @@ -316,14 +319,24 @@ If you need to completely replace the record retrieving code (e.g., you have a c ActiveAdmin.register Post do controller do def find_resource - Post.where(id: params[:id]).first! + scoped_collection.where(id: params[:id]).first! end end end ``` -Our controllers are built on [Inherited Resources](https://github.com/josevalim/inherited_resources), -so you can use [all of its features](https://github.com/josevalim/inherited_resources#overwriting-defaults). +Note that if you use an authorization library like CanCan, you should be careful to not +write code like this, otherwise **your authorization rules won't be applied**: + +```ruby +ActiveAdmin.register Post do + controller do + def find_resource + Post.where(id: params[:id]).first! + end + end +end +``` ## Belongs To From 48cc9e609d683f227797b826fe1d19f9a2723778 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 22 Nov 2015 21:47:16 -0600 Subject: [PATCH 0015/3836] capitalization change --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63c7102c1fe..8057afe2ac7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ * Rename `allow_comments` to `comments` for more consistent naming [#3695][] by [@pranas][] * JavaScript `window.AA` has been removed, use `window.ActiveAdmin` [#3606][] by [@timoschilling][] * `f.form_buffers` has been removed [#3486][] by [@varyonic][] -* iconic has been removed [#3553][] by [@timoschilling][] +* Iconic has been removed [#3553][] by [@timoschilling][] ### Enhancements From d787029e5523be2eb2ed99816eb0cecca2b72862 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 22 Nov 2015 22:50:02 -0600 Subject: [PATCH 0016/3836] fix typo in error message --- lib/active_admin/error.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/error.rb b/lib/active_admin/error.rb index 957e7fd0121..aa08717ea1b 100644 --- a/lib/active_admin/error.rb +++ b/lib/active_admin/error.rb @@ -33,7 +33,7 @@ def initialize(exception) super "Your file, #{file} (line #{line}), caused a database error while Active Admin was loading. This " + "is most common when your database is missing or doesn't have the latest migrations applied. To " + "prevent this error, move the code to a place where it will only be run when a page is rendered. " + - "One solution can be, to wrap the query in a Proc." + + "One solution can be, to wrap the query in a Proc. " + "Original error message: #{exception.message}" end From b4264a50878c87f81e762bbbd51eabb7b2890c96 Mon Sep 17 00:00:00 2001 From: Leonel Galan Date: Wed, 25 Nov 2015 11:08:01 -0500 Subject: [PATCH 0017/3836] Allows Hash-like objects to be used in attributes_table --- lib/active_admin/views/components/attributes_table.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/active_admin/views/components/attributes_table.rb b/lib/active_admin/views/components/attributes_table.rb index 5100b875e81..2c1d15a052e 100644 --- a/lib/active_admin/views/components/attributes_table.rb +++ b/lib/active_admin/views/components/attributes_table.rb @@ -5,7 +5,7 @@ class AttributesTable < ActiveAdmin::Component builder_method :attributes_table_for def build(obj, *attrs) - @collection = is_array?(obj) ? obj : [obj] + @collection = Array.wrap(obj) @resource_class = @collection.first.class options = { } options[:for] = @collection.first if single_record? @@ -102,10 +102,6 @@ def reflection_for(klass, method) def single_record? @single_record ||= @collection.size == 1 end - - def is_array?(obj) - obj.respond_to?(:each) && obj.respond_to?(:first) && !obj.is_a?(Hash) - end end end From e94e7b553e178843c1d240cc7ac4043c5cbd0a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stef=C3=A1n=20Vignir=20Skarph=C3=A9=C3=B0insson?= Date: Thu, 26 Nov 2015 16:25:36 +0100 Subject: [PATCH 0018/3836] Removing the condition to build the action items, to facilitate the use of JS to add buttons --- lib/active_admin/views/title_bar.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/views/title_bar.rb b/lib/active_admin/views/title_bar.rb index 416ecd9c758..8f32aca0199 100644 --- a/lib/active_admin/views/title_bar.rb +++ b/lib/active_admin/views/title_bar.rb @@ -47,7 +47,7 @@ def build_title_tag end def build_action_items - insert_tag(view_factory.action_items, @action_items) if @action_items.any? + insert_tag(view_factory.action_items, @action_items) end end From fe8fa2236dc327471873f9621b487e01c7961d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20Gy=C3=B6rffy?= Date: Mon, 7 Dec 2015 17:27:08 +0100 Subject: [PATCH 0019/3836] Fix Hungarian translation This tiny change fixes some gibberish in the Hungarian translation. --- config/locales/hu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 844f0315539..46f9b1b1b2e 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -83,7 +83,7 @@ hu: submit: "Belépés" reset_password: title: "Elfelejtette a jelszavát?" - submit: "Visszaállítása a jelszót" + submit: "Jelszó visszaállítása" change_password: title: "A jelszó módosítása" submit: "Jelszó módosítása" From e073d50bda140c71efbdabe46ff5124b30dacbdb Mon Sep 17 00:00:00 2001 From: Marco Mastrodonato Date: Wed, 9 Dec 2015 15:49:02 +0100 Subject: [PATCH 0020/3836] Added search status name in I18n :en, :it with default value for others --- config/locales/en.yml | 1 + config/locales/it.yml | 1 + lib/active_admin/filters/resource_extension.rb | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index b8614bfd73a..207fac2f8ec 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -32,6 +32,7 @@ en: greater_than: "Greater than" less_than: "Less than" search_status: + search_status_name: "Search status:" headline: "Scope:" current_filters: "Current filters:" no_current_filters: "None" diff --git a/config/locales/it.yml b/config/locales/it.yml index 15b28ff70be..2545a2eede6 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -32,6 +32,7 @@ it: greater_than: "Maggiore di" less_than: "Minore di" search_status: + search_status_name: "Situazione filtri:" headline: "Contesto:" current_filters: "Filtri attivi:" no_current_filters: "Nessuno" diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index 1b339519562..324b54efe0d 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -163,7 +163,7 @@ def add_search_status_sidebar_section end def search_status_section - ActiveAdmin::SidebarSection.new :search_status, only: :index, if: -> { params[:q] || params[:scope] } do + ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.search_status_name", :default => 'Search status'), only: :index, if: -> { params[:q] || params[:scope] } do active = ActiveAdmin::Filters::Active.new(resource_class, params) span do From ce7cc224535aee4938045bce0bbe451aee8eb1d1 Mon Sep 17 00:00:00 2001 From: Marco Mastrodonato Date: Wed, 9 Dec 2015 16:58:38 +0100 Subject: [PATCH 0021/3836] Renamed search_status.headline to current_scope, newtag in headline --- config/locales/ar.yml | 2 +- config/locales/de.yml | 2 +- config/locales/en.yml | 4 ++-- config/locales/es.yml | 2 +- config/locales/fr.yml | 2 +- config/locales/id.yml | 2 +- config/locales/it.yml | 4 ++-- config/locales/ja.yml | 2 +- config/locales/ko.yml | 2 +- config/locales/nl.yml | 2 +- config/locales/pt-BR.yml | 2 +- config/locales/ru.yml | 2 +- config/locales/sv-SE.yml | 2 +- config/locales/uk.yml | 2 +- config/locales/zh-CN.yml | 2 +- config/locales/zh-TW.yml | 2 +- lib/active_admin/filters/resource_extension.rb | 4 ++-- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index b62e6d6824a..2341f59d5d9 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -32,7 +32,7 @@ ar: greater_than: "أكبر من" less_than: "أقل من" search_status: - headline: "المجال:" + current_scope: "المجال:" current_filters: "المُرشحات الحاليّة:" no_current_filters: "بدون" status_tag: diff --git a/config/locales/de.yml b/config/locales/de.yml index 446e0022733..b29ec2315a3 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -32,7 +32,7 @@ de: greater_than: "Größer als" less_than: "Kleiner als" search_status: - headline: "Anwendungsbereich:" + current_scope: "Anwendungsbereich:" current_filters: "Aktuelle Filter:" no_current_filters: "Keine" status_tag: diff --git a/config/locales/en.yml b/config/locales/en.yml index 207fac2f8ec..8b18dfd7437 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -32,8 +32,8 @@ en: greater_than: "Greater than" less_than: "Less than" search_status: - search_status_name: "Search status:" - headline: "Scope:" + headline: "Search status:" + current_scope: "Scope:" current_filters: "Current filters:" no_current_filters: "None" status_tag: diff --git a/config/locales/es.yml b/config/locales/es.yml index c8f54d0f975..2eeb8a53007 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -32,7 +32,7 @@ es: greater_than: "Mayor que" less_than: "Menor que" search_status: - headline: "Alcance:" + current_scope: "Alcance:" current_filters: "Filtros actuales:" no_current_filters: "Ninguno" status_tag: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 91e985ac745..a0ba7e2fddd 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -32,7 +32,7 @@ fr: greater_than: "Plus grand que" less_than: "Plus petit que" search_status: - headline: "Etendu du filtre :" + current_scope: "Etendu du filtre :" current_filters: "Filtres actuels :" no_current_filters: "Aucun filtres" status_tag: diff --git a/config/locales/id.yml b/config/locales/id.yml index 8bc179eeb14..990632ddd59 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -32,7 +32,7 @@ id: greater_than: "Lebih besar dari" less_than: "Lebih kecil dari" search_status: - headline: "Scope:" + current_scope: "Scope:" current_filters: "Filter kini:" no_current_filters: "Tidak ada" status_tag: diff --git a/config/locales/it.yml b/config/locales/it.yml index 2545a2eede6..23f91a8b6c3 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -32,8 +32,8 @@ it: greater_than: "Maggiore di" less_than: "Minore di" search_status: - search_status_name: "Situazione filtri:" - headline: "Contesto:" + headline: "Situazione filtri:" + current_scope: "Contesto selezionato:" current_filters: "Filtri attivi:" no_current_filters: "Nessuno" status_tag: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 91ddbb4cc02..6903d0c23c0 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -32,7 +32,7 @@ ja: greater_than: "より大きい" less_than: "より小さい" search_status: - headline: "範囲:" + current_scope: "範囲:" current_filters: "現在の絞り込み:" no_current_filters: "なし" status_tag: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 1d54fa6b4c3..aa1f9118e5c 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -32,7 +32,7 @@ ko: greater_than: "초과" less_than: "미만" search_status: - headline: "검색 범위:" + current_scope: "검색 범위:" current_filters: "적용된 필터:" no_current_filters: "현재 적용된 필터가 없습니다" status_tag: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 661565f2958..699b42931fa 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -32,7 +32,7 @@ nl: greater_than: "Groter dan" less_than: "Kleiner dan" search_status: - headline: "Scope:" + current_scope: "Scope:" current_filters: "Huidige filters:" no_current_filters: "Geen" status_tag: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index e9f50a3ee67..27cdcbc48f7 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -32,7 +32,7 @@ pt-BR: greater_than: "Maior Que" less_than: "Menor Que" search_status: - headline: "Em:" + current_scope: "Em:" current_filters: "Filtros escolhidos:" no_current_filters: "Nenhum" status_tag: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 2eda9b94d84..9f699a0b7aa 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -32,7 +32,7 @@ ru: greater_than: "больше" less_than: "меньше" search_status: - headline: "Область:" + current_scope: "Область:" current_filters: "Текущий фильтр:" no_current_filters: "Ни один" status_tag: diff --git a/config/locales/sv-SE.yml b/config/locales/sv-SE.yml index 0b7d4d6d6f3..693ab9490f0 100644 --- a/config/locales/sv-SE.yml +++ b/config/locales/sv-SE.yml @@ -32,7 +32,7 @@ greater_than: "Större än" less_than: "Mindre än" search_status: - headline: "Scope:" + current_scope: "Scope:" current_filters: "Nuvarande filter:" no_current_filters: "Inga" status_tag: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 509bd482b07..863eaa46416 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -32,7 +32,7 @@ uk: greater_than: "більше" less_than: "меньше" search_status: - headline: "Область:" + current_scope: "Область:" current_filters: "Поточний фільтр:" no_current_filters: "Жоден" status_tag: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index ee3fa7ec335..1fcc499fb10 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -32,7 +32,7 @@ greater_than: "大于" less_than: "小于" search_status: - headline: "搜索范围:" + current_scope: "搜索范围:" current_filters: "过滤条件:" no_current_filters: "无" status_tag: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 67d14f79693..f8969952fb8 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -32,7 +32,7 @@ greater_than: "大於" less_than: "小於" search_status: - headline: "子集:" + current_scope: "子集:" current_filters: "目前篩選條件:" no_current_filters: "無" status_tag: diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index 324b54efe0d..387ca9e3c51 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -163,11 +163,11 @@ def add_search_status_sidebar_section end def search_status_section - ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.search_status_name", :default => 'Search status'), only: :index, if: -> { params[:q] || params[:scope] } do + ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.headline", :default => 'Search status'), only: :index, if: -> { params[:q] || params[:scope] } do active = ActiveAdmin::Filters::Active.new(resource_class, params) span do - h4 I18n.t("active_admin.search_status.headline"), style: 'display: inline' + h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline' b active.scope, style: "display: inline" div style: "margin-top: 10px" do From 905eb7ea214dc68615cceb6c62c337c15245e033 Mon Sep 17 00:00:00 2001 From: Marco Mastrodonato Date: Thu, 10 Dec 2015 10:54:15 +0100 Subject: [PATCH 0022/3836] Fixed chars cannot start any token en.yml at line 35 column 1 --- config/locales/en.yml | 2 +- config/locales/it.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 8b18dfd7437..6ee2dd4bfb1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -32,7 +32,7 @@ en: greater_than: "Greater than" less_than: "Less than" search_status: - headline: "Search status:" + headline: "Search status:" current_scope: "Scope:" current_filters: "Current filters:" no_current_filters: "None" diff --git a/config/locales/it.yml b/config/locales/it.yml index 23f91a8b6c3..f24a348bc2a 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -32,7 +32,7 @@ it: greater_than: "Maggiore di" less_than: "Minore di" search_status: - headline: "Situazione filtri:" + headline: "Situazione filtri:" current_scope: "Contesto selezionato:" current_filters: "Filtri attivi:" no_current_filters: "Nessuno" From 348159992d3831de9a204362dd03ee547000a3a7 Mon Sep 17 00:00:00 2001 From: Marco Mastrodonato Date: Thu, 10 Dec 2015 11:29:53 +0100 Subject: [PATCH 0023/3836] Misprint default value, updated spec --- lib/active_admin/filters/resource_extension.rb | 2 +- spec/unit/dsl_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index 387ca9e3c51..d6cbe45a8a5 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -163,7 +163,7 @@ def add_search_status_sidebar_section end def search_status_section - ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.headline", :default => 'Search status'), only: :index, if: -> { params[:q] || params[:scope] } do + ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.headline"), only: :index, if: -> { params[:q] || params[:scope] } do active = ActiveAdmin::Filters::Active.new(resource_class, params) span do diff --git a/spec/unit/dsl_spec.rb b/spec/unit/dsl_spec.rb index 5eff8aa22ef..d158cbe2223 100644 --- a/spec/unit/dsl_spec.rb +++ b/spec/unit/dsl_spec.rb @@ -97,7 +97,7 @@ def self.included(dsl) dsl.run_registration_block do sidebar :help end - expect(dsl.config.sidebar_sections.map(&:name)).to match_array %w{filters search_status email help} + expect(dsl.config.sidebar_sections.map(&:name)).to match_array %w{filters search status email help} end end From c173e2c56558be819f66f0a4f0baa92003568638 Mon Sep 17 00:00:00 2001 From: Marco Mastrodonato Date: Thu, 10 Dec 2015 11:43:24 +0100 Subject: [PATCH 0024/3836] Further update to dsl spec --- spec/unit/dsl_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/dsl_spec.rb b/spec/unit/dsl_spec.rb index d158cbe2223..ec599efb3d2 100644 --- a/spec/unit/dsl_spec.rb +++ b/spec/unit/dsl_spec.rb @@ -97,7 +97,7 @@ def self.included(dsl) dsl.run_registration_block do sidebar :help end - expect(dsl.config.sidebar_sections.map(&:name)).to match_array %w{filters search status email help} + expect(dsl.config.sidebar_sections.map(&:name)).to match_array ['filters', 'Search status:', 'email', 'help'] end end From 3157f2d70cbab780fae257c7e80b84275ce286e1 Mon Sep 17 00:00:00 2001 From: Leon Strachan Date: Thu, 10 Dec 2015 10:23:17 +0000 Subject: [PATCH 0025/3836] add edit action to id_column if show action not available modified: lib/active_admin/views/index_as_table.rb --- lib/active_admin/views/index_as_table.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/active_admin/views/index_as_table.rb b/lib/active_admin/views/index_as_table.rb index 6734b14b416..3eabc1ae2fb 100644 --- a/lib/active_admin/views/index_as_table.rb +++ b/lib/active_admin/views/index_as_table.rb @@ -270,6 +270,8 @@ def id_column column(resource_class.human_attribute_name(resource_class.primary_key), sortable: resource_class.primary_key) do |resource| if controller.action_methods.include?('show') link_to resource.id, resource_path(resource), class: "resource_id_link" + elsif controller.action_methods.include?('edit') + link_to resource.id, edit_resource_path(resource), class: "resource_id_link" else resource.id end From 5428550bead8bb53746c8be83f4f06481dd6d644 Mon Sep 17 00:00:00 2001 From: Ferdinand Rosario Date: Thu, 10 Dec 2015 11:48:52 +0530 Subject: [PATCH 0026/3836] Updated patch and gem version --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3a857a26e2..074eb39bc8f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,14 +12,15 @@ script: - bundle exec rake test_with_coveralls rvm: - 1.9 + - 2.1.7 - 2.2.3 - - jruby-9.0.0.0 + - jruby-9.0.4.0 env: matrix: - RAILS=3.2.22 - - RAILS=4.1.13 + - RAILS=4.1.14 - RAILS=master - - RAILS=4.2.4 + - RAILS=4.2.5 global: - JRUBY_OPTS="-J-Xmx1024m --debug" matrix: From 0d57e6c4eaebf0fb49aa51539cdbea48abb061c3 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 24 Dec 2015 12:31:56 -0600 Subject: [PATCH 0027/3836] fix test rails app generation so it doesn't include turbolinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit also, don’t create a Gemfile or create various stub files --- script/local | 11 ++++++++++- spec/support/rails_template.rb | 3 --- tasks/test.rake | 17 +++++++++++++---- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/script/local b/script/local index 8c4081d142b..6f0cda59382 100755 --- a/script/local +++ b/script/local @@ -29,7 +29,16 @@ system "mkdir #{test_app_dir}" unless File.exists?(test_app_dir) # Create the sample rails app if it doesn't already exist unless File.exists? test_app_path - system "RAILS='#{rails_version}' bundle exec rails new #{test_app_path} -m spec/support/rails_template_with_data.rb --skip-bundle" + args = %w[ + -m\ spec/support/rails_template_with_data.rb + --skip-gemfile + --skip-bundle + --skip-git + --skip-keeps + --skip-turbolinks + --skip-test-unit + ] + system "RAILS='#{rails_version}' bundle exec rails new #{test_app_path} #{args.join ' '}" end # Link this rails app diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 056932c6414..edadb1f3750 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -1,8 +1,5 @@ # Rails template to build the sample app for specs -run "rm Gemfile" -run "rm -r test" - # Create a cucumber database and environment copy_file File.expand_path('../templates/cucumber.rb', __FILE__), "config/environments/cucumber.rb" copy_file File.expand_path('../templates/cucumber_with_reloading.rb', __FILE__), "config/environments/cucumber_with_reloading.rb" diff --git a/tasks/test.rake b/tasks/test.rake index 906e00fb62b..9f8fef46051 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,12 +1,21 @@ desc "Creates a test rails app for the specs to run against" -task :setup, :parallel do |t, args| +task :setup, :parallel do |t, opts| require 'rails/version' if File.exists? dir = "spec/rails/rails-#{Rails::VERSION::STRING}" puts "test app #{dir} already exists; skipping" else - system("mkdir spec/rails") unless File.exists?("spec/rails") - system "#{'INSTALL_PARALLEL=yes' if args[:parallel]} bundle exec rails new #{dir} -m spec/support/rails_template.rb --skip-bundle" - Rake::Task['parallel:after_setup_hook'].invoke if args[:parallel] + system 'mkdir -p spec/rails' + args = %w[ + -m\ spec/support/rails_template.rb + --skip-gemfile + --skip-bundle + --skip-git + --skip-keeps + --skip-turbolinks + --skip-test-unit + ] + system "#{'INSTALL_PARALLEL=yes' if opts[:parallel]} bundle exec rails new #{dir} #{args.join ' '}" + Rake::Task['parallel:after_setup_hook'].invoke if opts[:parallel] end end From ae304db87fc7318f64ad23f3af28eec08e0b3857 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 24 Dec 2015 13:03:01 -0600 Subject: [PATCH 0028/3836] don't digest assets in test environment --- spec/support/rails_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index edadb1f3750..a1f0e845069 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -79,7 +79,7 @@ def set_id }, after: 'class Tagging < ActiveRecord::Base' # Configure default_url_options in test environment -inject_into_file "config/environments/test.rb", " config.action_mailer.default_url_options = { host: 'example.com' }\n", after: "config.cache_classes = true\n" +inject_into_file "config/environments/test.rb", " config.action_mailer.default_url_options = { host: 'example.com' }\n config.assets.digest = false\n", after: "config.cache_classes = true\n" # Add our local Active Admin to the load path inject_into_file "config/environment.rb", "\n$LOAD_PATH.unshift('#{File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))}')\nrequire \"active_admin\"\n", after: "require File.expand_path('../application', __FILE__)" From aca5dbdffd7e7301db4c5bbc76bb9c986d148f84 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 24 Dec 2015 13:05:11 -0600 Subject: [PATCH 0029/3836] don't test against Ruby 2.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit doing so just slows down our test suite. Ruby 2.1 and 2.2 aren’t sufficiently different that it’s worth running the tests against both --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 074eb39bc8f..bb125161496 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ script: - bundle exec rake test_with_coveralls rvm: - 1.9 - - 2.1.7 - 2.2.3 - jruby-9.0.4.0 env: From f57c5a6a416cdac972d8176641aafb9bca7a62d7 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 24 Dec 2015 13:09:57 -0600 Subject: [PATCH 0030/3836] only run test suite on master and stable branches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit that way if feature branches are created on the main repo, Travis doesn’t run the test suite twice --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index bb125161496..4f5d57e299a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,10 @@ matrix: env: RAILS=master allow_failures: - env: RAILS=master +branches: + only: + - master + - /\A\d-\d-stable\z/ notifications: irc: channels: From cb5d8ab0c3161cc56353053d28a5bcadd4407e0d Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 24 Dec 2015 14:15:57 -0600 Subject: [PATCH 0031/3836] style changes to the Rails app template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit also gets the root redirect working. It wasn’t working because its regular expression was out of date. Unfortunately the redirection breaks the test suite, so I changed it to only be added in development. --- spec/support/rails_template.rb | 233 ++++++++++++++++++++------------- 1 file changed, 144 insertions(+), 89 deletions(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index a1f0e845069..1a8f428bb1a 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -1,8 +1,8 @@ # Rails template to build the sample app for specs # Create a cucumber database and environment -copy_file File.expand_path('../templates/cucumber.rb', __FILE__), "config/environments/cucumber.rb" -copy_file File.expand_path('../templates/cucumber_with_reloading.rb', __FILE__), "config/environments/cucumber_with_reloading.rb" +copy_file File.expand_path('../templates/cucumber.rb', __FILE__), 'config/environments/cucumber.rb' +copy_file File.expand_path('../templates/cucumber_with_reloading.rb', __FILE__), 'config/environments/cucumber_with_reloading.rb' gsub_file 'config/database.yml', /^test:.*\n/, "test: &test\n" gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *test\n database: db/cucumber.sqlite3" @@ -13,103 +13,158 @@ gsub_file 'config/secrets.yml', /\z/, "\ncucumber_with_reloading:\n secret_key_base: #{'o' * 128}" end -generate :model, "post title:string body:text published_at:datetime author_id:integer position:integer custom_category_id:integer starred:boolean foo_id:integer" -inject_into_file 'app/models/post.rb', %q{ - belongs_to :category, foreign_key: :custom_category_id - belongs_to :author, class_name: 'User' - has_many :taggings - accepts_nested_attributes_for :author - accepts_nested_attributes_for :taggings - attr_accessible :author, :position unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes -}, after: 'class Post < ActiveRecord::Base' -copy_file File.expand_path('../templates/post_decorator.rb', __FILE__), "app/models/post_decorator.rb" - -generate :model, "blog/post title:string body:text published_at:datetime author_id:integer position:integer custom_category_id:integer starred:boolean foo_id:integer" -inject_into_file 'app/models/blog/post.rb', %q{ - belongs_to :category, foreign_key: :custom_category_id - belongs_to :author, class_name: 'User' - has_many :taggings - accepts_nested_attributes_for :author - accepts_nested_attributes_for :taggings - attr_accessible :author, :position unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes -}, after: 'class Blog::Post < ActiveRecord::Base' - - -generate :model, "profile user_id:integer bio:text" -generate :model, "user type:string first_name:string last_name:string username:string age:integer" -inject_into_file 'app/models/user.rb', %q{ - has_many :posts, foreign_key: 'author_id' - has_one :profile - accepts_nested_attributes_for :profile, allow_destroy: true - def display_name - "#{first_name} #{last_name}" +generate :model, 'post title:string body:text published_at:datetime author_id:integer ' + + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' +create_file 'app/models/post.rb', <<-RUBY.strip_heredoc, force: true + class Post < ActiveRecord::Base + belongs_to :category, foreign_key: :custom_category_id + belongs_to :author, class_name: 'User' + has_many :taggings + accepts_nested_attributes_for :author + accepts_nested_attributes_for :taggings + + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes + attr_accessible :id, :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id + end end -}, after: 'class User < ActiveRecord::Base' +RUBY +copy_file File.expand_path('../templates/post_decorator.rb', __FILE__), 'app/models/post_decorator.rb' + +generate :model, 'blog/post title:string body:text published_at:datetime author_id:integer ' + + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' +create_file 'app/models/blog/post.rb', <<-RUBY.strip_heredoc, force: true + class Blog::Post < ActiveRecord::Base + belongs_to :category, foreign_key: :custom_category_id + belongs_to :author, class_name: 'User' + has_many :taggings + accepts_nested_attributes_for :author + accepts_nested_attributes_for :taggings + + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes + attr_accessible :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id + end + end +RUBY + +generate :model, 'profile user_id:integer bio:text' + +generate :model, 'user type:string first_name:string last_name:string username:string age:integer' +create_file 'app/models/user.rb', <<-RUBY.strip_heredoc, force: true + class User < ActiveRecord::Base + has_many :posts, foreign_key: 'author_id' + has_one :profile + accepts_nested_attributes_for :profile, allow_destroy: true + + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes + attr_accessible :first_name, :last_name, :username, :age + end -inject_into_file 'app/models/profile.rb', %q{ - belongs_to :user -}, after: 'class Profile < ActiveRecord::Base' + def display_name + "\#{first_name} \#{last_name}" + end + end +RUBY + +create_file 'app/models/profile.rb', <<-RUBY.strip_heredoc, force: true + class Profile < ActiveRecord::Base + belongs_to :user + end +RUBY generate :model, 'publisher --migration=false --parent=User' + generate :model, 'category name:string description:text' -inject_into_file 'app/models/category.rb', %q{ - has_many :posts, foreign_key: :custom_category_id - has_many :authors, through: :posts - accepts_nested_attributes_for :posts -}, after: 'class Category < ActiveRecord::Base' +create_file 'app/models/category.rb', <<-RUBY.strip_heredoc, force: true + class Category < ActiveRecord::Base + has_many :posts, foreign_key: :custom_category_id + has_many :authors, through: :posts + accepts_nested_attributes_for :posts + + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes + attr_accessible :name + end + end +RUBY + generate :model, 'store name:string' # Generate a model with string ids -generate :model, "tag name:string" -gsub_file(Dir['db/migrate/*_create_tags.rb'][0], /\:tags\sdo\s.*/, ":tags, id: false, primary_key: :id do |t|\n\t\t\tt.string :id\n") -inject_into_file 'app/models/tag.rb', %q{ - self.primary_key = :id - before_create :set_id - - private - def set_id - self.id = 8.times.inject("") { |s,e| s << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr } +generate :model, 'tag name:string' +gsub_file Dir['db/migrate/*_create_tags.rb'].first, /\:tags do .*/, <<-RUBY.strip_heredoc + :tags, id: false, primary_key: :id do |t| + t.string :id +RUBY +create_file 'app/models/tag.rb', <<-RUBY.strip_heredoc, force: true + class Tag < ActiveRecord::Base + self.primary_key = :id + before_create :set_id + + private + def set_id + self.id = SecureRandom.uuid + end + + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes + attr_accessible :name + end end -}, after: 'class Tag < ActiveRecord::Base' +RUBY + +generate :model, 'tagging post_id:integer tag_id:integer' +create_file 'app/models/tagging.rb', <<-RUBY.strip_heredoc, force: true + class Tagging < ActiveRecord::Base + belongs_to :post + belongs_to :tag + end +RUBY + +inject_into_file 'config/environments/test.rb', <<-RUBY, after: 'config.cache_classes = true' -generate :model, "tagging post_id:integer tag_id:integer" -inject_into_file 'app/models/tagging.rb', %q{ - belongs_to :post - belongs_to :tag -}, after: 'class Tagging < ActiveRecord::Base' + config.action_mailer.default_url_options = {host: 'example.com'} + config.assets.digest = false -# Configure default_url_options in test environment -inject_into_file "config/environments/test.rb", " config.action_mailer.default_url_options = { host: 'example.com' }\n config.assets.digest = false\n", after: "config.cache_classes = true\n" +RUBY # Add our local Active Admin to the load path -inject_into_file "config/environment.rb", "\n$LOAD_PATH.unshift('#{File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))}')\nrequire \"active_admin\"\n", after: "require File.expand_path('../application', __FILE__)" -inject_into_file "config/application.rb", "\nrequire 'devise'\n", after: "require 'rails/all'" +inject_into_file 'config/environment.rb', <<-RUBY, after: "require File.expand_path('../application', __FILE__)" + +$LOAD_PATH.unshift '#{File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))}' +require 'active_admin' + +RUBY # Force strong parameters to raise exceptions -inject_into_file 'config/application.rb', "\n\n config.action_controller.action_on_unpermitted_parameters = :raise if Rails::VERSION::MAJOR == 4\n\n", after: 'class Application < Rails::Application' +inject_into_file 'config/application.rb', <<-RUBY, after: 'class Application < Rails::Application' + + config.action_controller.action_on_unpermitted_parameters = :raise if Rails::VERSION::MAJOR == 4 + +RUBY # Add some translations -append_file "config/locales/en.yml", File.read(File.expand_path('../templates/en.yml', __FILE__)) +append_file 'config/locales/en.yml', File.read(File.expand_path('../templates/en.yml', __FILE__)) # Add predefined admin resources -directory File.expand_path('../templates/admin', __FILE__), "app/admin" +directory File.expand_path('../templates/admin', __FILE__), 'app/admin' # Add predefined policies directory File.expand_path('../templates/policies', __FILE__), 'app/policies' -$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) +$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib') generate 'active_admin:install' -inject_into_file "config/routes.rb", "\n root to: redirect('/admin')", after: /.*::Application.routes.draw do/ -remove_file "public/index.html" if File.exists? "public/index.html" +if ENV['RAILS_ENV'] != 'test' + inject_into_file 'config/routes.rb', "\n root to: redirect('admin')", after: /.*routes.draw do/ +end + +remove_file 'public/index.html' if File.exists? 'public/index.html' # remove once Rails 3.2 support is dropped # Devise master doesn't set up its secret key on Rails 4.1 # https://github.com/plataformatec/devise/issues/2554 gsub_file 'config/initializers/devise.rb', /# config.secret_key =/, 'config.secret_key =' -rake "db:migrate db:test:prepare" -run "/usr/bin/env RAILS_ENV=cucumber rake db:migrate" +rake 'db:migrate db:test:prepare' +run '/usr/bin/env RAILS_ENV=cucumber rake db:migrate' if ENV['INSTALL_PARALLEL'] inject_into_file 'config/database.yml', "<%= ENV['TEST_ENV_NUMBER'] %>", after: 'test.sqlite3' @@ -118,25 +173,25 @@ def set_id # Note: this is hack! # Somehow, calling parallel_tests tasks from Rails generator using Thor does not work ... # RAILS_ENV variable never makes it to parallel_tests tasks. - # We need to call these tasks in the after set up hook in order to creates cucumber DBs + run migrations on test & cucumber DBs - create_file 'lib/tasks/parallel.rake', %q{ -namespace :parallel do - def run_in_parallel(cmd, options) - count = "-n #{options[:count]}" if options[:count] - executable = 'parallel_test' - command = "#{executable} --exec '#{cmd}' #{count} #{'--non-parallel' if options[:non_parallel]}" - abort unless system(command) - end - - desc "create cucumber databases via db:create --> parallel:create_cucumber_db[num_cpus]" - task :create_cucumber_db, :count do |t, args| - run_in_parallel("rake db:create RAILS_ENV=cucumber", args) - end - - desc "load dumped schema for cucumber databases" - task :load_schema_cucumber_db, :count do |t,args| - run_in_parallel("rake db:schema:load RAILS_ENV=cucumber", args) - end -end -} + # We need to call these tasks in the after set up hook in order to create cucumber DBs + run migrations on test & cucumber DBs + create_file 'lib/tasks/parallel.rake', <<-RUBY.strip_heredoc + namespace :parallel do + def run_in_parallel(cmd, options) + count = "-n #{options[:count]}" if options[:count] + executable = 'parallel_test' + command = "#{executable} --exec '#{cmd}' #{count} #{'--non-parallel' if options[:non_parallel]}" + abort unless system(command) + end + + desc "create cucumber databases via db:create --> parallel:create_cucumber_db[num_cpus]" + task :create_cucumber_db, :count do |t, args| + run_in_parallel("rake db:create RAILS_ENV=cucumber", args) + end + + desc "load dumped schema for cucumber databases" + task :load_schema_cucumber_db, :count do |t,args| + run_in_parallel("rake db:schema:load RAILS_ENV=cucumber", args) + end + end + RUBY end From 5f190fba809a20f3cae83cc547d1a9003e91193f Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Thu, 31 Dec 2015 14:47:01 -0600 Subject: [PATCH 0032/3836] #4225: prevent namespaced classes from breaking installer --- lib/generators/active_admin/install/install_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/active_admin/install/install_generator.rb b/lib/generators/active_admin/install/install_generator.rb index eb408a1ec4c..6b7844ddb88 100644 --- a/lib/generators/active_admin/install/install_generator.rb +++ b/lib/generators/active_admin/install/install_generator.rb @@ -11,7 +11,7 @@ class InstallGenerator < ActiveRecord::Generators::Base source_root File.expand_path("../templates", __FILE__) def copy_initializer - @underscored_user_name = name.underscore + @underscored_user_name = name.underscore.gsub('/', '_') @use_authentication_method = options[:users].present? template 'active_admin.rb.erb', 'config/initializers/active_admin.rb' end From 44e6b83ad41b9332156e75db8434324dfad63960 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 2 Jan 2016 21:57:49 -0600 Subject: [PATCH 0033/3836] #4256: document security issue with CSV exports --- docs/14-gotchas.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index f54d782d73b..cc2cf729250 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -1,5 +1,11 @@ #Gotchas +## Security + +### Spreadsheet applications vulnerable to unescaped CSV data + +If your CSV export includes untrusted data provided by your users, it's possible that they could include an executable formula that could call arbitrary commands on your computer. See [#4256](https://github.com/activeadmin/activeadmin/issues/4256) for more details. + ## Session Commits & Asset Pipeline When configuring the asset pipeline ensure that the asset prefix @@ -91,4 +97,4 @@ YourModel.solr_search ``` ## Authentication & Application Controller -The `ActiveAdmin::BaseController` inherits from the `ApplicationController`. Any authentication method(s) specified in the `ApplicationController` callbacks will be called instead of the authentication method in the active admin config file. For example, if the ApplicationController has a callback `before_action :custom_authentication_method` and the config file's authentication method is `config.authentication_method = :authenticate_active_admin_user`, then `custom_authentication_method` will be called instead of `authenticate_active_admin_user`. \ No newline at end of file +The `ActiveAdmin::BaseController` inherits from the `ApplicationController`. Any authentication method(s) specified in the `ApplicationController` callbacks will be called instead of the authentication method in the active admin config file. For example, if the ApplicationController has a callback `before_action :custom_authentication_method` and the config file's authentication method is `config.authentication_method = :authenticate_active_admin_user`, then `custom_authentication_method` will be called instead of `authenticate_active_admin_user`. From 168e5e429a788e499a94d1b6b1056c451f999165 Mon Sep 17 00:00:00 2001 From: Roger Kind Kristiansen Date: Mon, 4 Jan 2016 10:23:35 +0100 Subject: [PATCH 0034/3836] Add Norwegian (nb) translations for search_status I've left the current_scope translation out since there really isn't any good Norwegian translation that fits in this context. --- config/locales/nb.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/locales/nb.yml b/config/locales/nb.yml index e21370ba8d3..d545df97131 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -31,6 +31,10 @@ nb: ends_with: "Slutter med" greater_than: "Større enn" less_than: "Mindre enn" + search_status: + headline: "Søkestatus:" + current_filters: "Gjeldende filtre:" + no_current_filters: "Ingen" status_tag: "yes": "Ja" "no": "Nei" From 1ec18632a8774056f068dfe28406212abbb4fdb4 Mon Sep 17 00:00:00 2001 From: Alexander Marchenko Date: Mon, 11 Jan 2016 03:52:09 +0300 Subject: [PATCH 0035/3836] ru locale fix --- config/locales/ru.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 9f699a0b7aa..12b27855648 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -40,7 +40,7 @@ ru: "no": "Нет" main_content: "Создайте %{model}#main_content для отображения содержимого." logout: "Выйти" - powered_by: "Powered by %{active_admin} %{version}" + powered_by: "Работает на %{active_admin} %{version}" sidebars: filters: "Фильтры" search_status: "Статус поиска" @@ -126,7 +126,7 @@ ru: resend_unlock_instructions: "Повторная отправка инструкций разблокировки" resend_confirmation_instructions: "Повторная отправка инструкций подтверждения" unsupported_browser: - headline: "Пожалуйста, обратите внимание, что ActiveAdmin больше не поддерживает Internet Explorer 8 версии и старее" + headline: "Пожалуйста, обратите внимание, что Active Admin больше не поддерживает старые версии Internet Explorer начиная с версии IE 8" recommendation: "Мы рекомендуем обновить версию вашего браузера (Internet Explorer, Google Chrome, или Firefox)." turn_off_compatibility_view: "Если вы используете IE 9 или новее, убедитесь, что вы выключили опцию \"Просмотр в режиме совместимости\"." access_denied: From cdaabf8af4338fc49c0052e2837263c60b26b889 Mon Sep 17 00:00:00 2001 From: Fabien MICHEL Date: Wed, 20 Jan 2016 12:09:35 +0100 Subject: [PATCH 0036/3836] Allow usage of wrapper_html option in filters --- lib/active_admin/inputs/filters/base.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/inputs/filters/base.rb b/lib/active_admin/inputs/filters/base.rb index 48a18710357..420a17c4937 100644 --- a/lib/active_admin/inputs/filters/base.rb +++ b/lib/active_admin/inputs/filters/base.rb @@ -24,7 +24,9 @@ def label_from_options end def wrapper_html_options - { class: "filter_form_field filter_#{as}" } + opts = super + (opts[:class] ||= '') << " filter_form_field filter_#{as}" + opts end # Override the standard finder to accept a proc From 1ebb0d49f0c3ce97bd0487fed436f7d11086489a Mon Sep 17 00:00:00 2001 From: Fabien MICHEL Date: Wed, 20 Jan 2016 12:40:03 +0100 Subject: [PATCH 0037/3836] Add missing fr translation --- config/locales/fr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index a0ba7e2fddd..af7037f7790 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -32,6 +32,7 @@ fr: greater_than: "Plus grand que" less_than: "Plus petit que" search_status: + headline: "Statut de la recherche :" current_scope: "Etendu du filtre :" current_filters: "Filtres actuels :" no_current_filters: "Aucun filtres" From 96cecb890665acd75d57922506a0d1679077752c Mon Sep 17 00:00:00 2001 From: Maciej Rzasa Date: Wed, 20 Jan 2016 20:22:50 +0100 Subject: [PATCH 0038/3836] Method #decorate? should use form.options[:decorate] --- lib/active_admin/resource_controller/decorators.rb | 2 +- spec/unit/resource_controller/decorators_spec.rb | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/resource_controller/decorators.rb b/lib/active_admin/resource_controller/decorators.rb index 33fff8c531b..c0c02a1ad5b 100644 --- a/lib/active_admin/resource_controller/decorators.rb +++ b/lib/active_admin/resource_controller/decorators.rb @@ -28,7 +28,7 @@ def self.undecorate(resource) def decorate? case action_name - when 'new', 'edit' + when 'new', 'edit', 'create', 'update' form = active_admin_config.get_page_presenter :form form && form.options[:decorate] && decorator_class.present? else diff --git a/spec/unit/resource_controller/decorators_spec.rb b/spec/unit/resource_controller/decorators_spec.rb index 7edf6386005..f18cad39f2c 100644 --- a/spec/unit/resource_controller/decorators_spec.rb +++ b/spec/unit/resource_controller/decorators_spec.rb @@ -28,14 +28,26 @@ def self.name context 'with a decorator configured' do let(:decorator_class) { PostDecorator } it { is_expected.to be_kind_of(PostDecorator) } + + context 'with form' do + let(:action) { 'update' } + + it "does not decorate when :decorate is set to false" do + form = double + allow(form).to receive(:options).and_return(:decorate => false) + allow(active_admin_config).to receive(:get_page_presenter).and_return(form) + is_expected.not_to be_kind_of(PostDecorator) + end + end end context 'with no decorator configured' do let(:decorator_class) { nil } it { is_expected.to be_kind_of(Post) } end - end + end +` describe '#apply_collection_decorator' do before { Post.create! } let(:action) { 'index' } From d79b3cbb2daec7b9f3da7d649de4258ae138878f Mon Sep 17 00:00:00 2001 From: Maciej Rzasa Date: Mon, 25 Jan 2016 23:16:19 +0100 Subject: [PATCH 0039/3836] fixed typo in spec --- spec/unit/resource_controller/decorators_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/unit/resource_controller/decorators_spec.rb b/spec/unit/resource_controller/decorators_spec.rb index f18cad39f2c..e9258366400 100644 --- a/spec/unit/resource_controller/decorators_spec.rb +++ b/spec/unit/resource_controller/decorators_spec.rb @@ -45,9 +45,8 @@ def self.name let(:decorator_class) { nil } it { is_expected.to be_kind_of(Post) } end - end -` + describe '#apply_collection_decorator' do before { Post.create! } let(:action) { 'index' } From cc85abc99a221b84ae67625843b7e4cb7b850b1e Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Mon, 25 Jan 2016 17:26:10 -0600 Subject: [PATCH 0040/3836] #4286: reword install docs for better clarity --- docs/0-installation.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/0-installation.md b/docs/0-installation.md index 3b4c8466185..dd951fb9d12 100644 --- a/docs/0-installation.md +++ b/docs/0-installation.md @@ -17,16 +17,22 @@ that can be injected into your existing Ruby on Rails application. ## Setting up Active Admin -After installing the gem, you need to run the generator. By default we use Devise, and -the generator creates an `AdminUser` model. If you want to create a different model -(or modify an existing one for use with Devise) you can pass it as an argument. -If you want to skip Devise configuration entirely, you can pass `--skip-users`. - -```sh -rails g active_admin:install # creates the AdminUser class -rails g active_admin:install User # creates / edits the class for use with Devise -rails g active_admin:install --skip-users # skips Devise install -``` +After installing the gem, you need to run the generator. Here are your options: + +- If you don't want to use Devise, run it with `--skip-users`: + ```sh + rails g active_admin:install --skip-users + ``` + +- If you want to use an existing user class, provide it as an argument: + ```sh + rails g active_admin:install User + ``` + +- Otherwise, with no arguments we will create an `AdminUser` class to use with Devise: + ```sh + rails g active_admin:install + ``` The generator adds these core files, among others: From f5c14e29ec11364d1049529ef460dea77126eb0f Mon Sep 17 00:00:00 2001 From: Sergey Kuchmistov Date: Tue, 26 Jan 2016 18:24:14 +0300 Subject: [PATCH 0041/3836] Hide bulk actions button if there aren't displayed actions inside --- features/index/batch_actions.feature | 13 +++++++++++++ .../batch_actions/views/batch_action_selector.rb | 1 + 2 files changed, 14 insertions(+) diff --git a/features/index/batch_actions.feature b/features/index/batch_actions.feature index 92e7031a6e8..3a12e410c29 100644 --- a/features/index/batch_actions.feature +++ b/features/index/batch_actions.feature @@ -64,6 +64,19 @@ Feature: Batch Actions Then I should see a flash with "Successfully destroyed 2 posts" And I should see 3 posts in the table + Scenario: Disable display of batch action button if all nested buttons hide + Given 1 post exist + And an index configuration of: + """ + ActiveAdmin.register Post do + batch_action :destroy, false + batch_action(:flag, if: proc { false } ) do + render text: 42 + end + end + """ + Then I should not see the batch action selector + Scenario: Using a custom batch action Given 10 posts exist And an index configuration of: diff --git a/lib/active_admin/batch_actions/views/batch_action_selector.rb b/lib/active_admin/batch_actions/views/batch_action_selector.rb index cf370812141..3722194f75e 100644 --- a/lib/active_admin/batch_actions/views/batch_action_selector.rb +++ b/lib/active_admin/batch_actions/views/batch_action_selector.rb @@ -23,6 +23,7 @@ def to_s private def build_drop_down + return if batch_actions_to_display.empty? dropdown_menu I18n.t("active_admin.batch_actions.button_label"), class: "batch_actions_selector dropdown_menu", button: { class: "disabled" } do From 30af8ff9341dd5b23fa50efdbd6c4c34c7321224 Mon Sep 17 00:00:00 2001 From: Takayasu Oyama Date: Wed, 27 Jan 2016 14:44:27 +0900 Subject: [PATCH 0042/3836] add headline translation to ja.yml --- config/locales/ja.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 6903d0c23c0..fa1918ceb59 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -32,6 +32,7 @@ ja: greater_than: "より大きい" less_than: "より小さい" search_status: + headline: "検索条件:" current_scope: "範囲:" current_filters: "現在の絞り込み:" no_current_filters: "なし" From 2699c227a9cd20b97ccabfd7b1c38559802f546e Mon Sep 17 00:00:00 2001 From: daino3 Date: Thu, 4 Feb 2016 15:37:14 -0600 Subject: [PATCH 0043/3836] using AUTH constants for menu generation --- lib/active_admin/resource/menu.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/resource/menu.rb b/lib/active_admin/resource/menu.rb index 771519f988c..9c8d22e097a 100644 --- a/lib/active_admin/resource/menu.rb +++ b/lib/active_admin/resource/menu.rb @@ -27,7 +27,7 @@ def default_menu_options id: resource_name.plural, label: proc{ resource.plural_resource_label }, url: proc{ resource.route_collection_path(params) }, - if: proc{ authorized?(:read, menu_resource_class) } + if: proc{ authorized?(Auth::READ, menu_resource_class) } } end From 826599f4da29768fec7cdac65849782e6dd7fb0b Mon Sep 17 00:00:00 2001 From: oveits Date: Fri, 5 Feb 2016 18:17:40 +0100 Subject: [PATCH 0044/3836] Correct path in active_admin.scss In the comments, the path `app/assets/stylesheets/active_admin/mixins/_variables.css.scss` is incorrect and needs to be changed to `app/assets/stylesheets/active_admin/mixins/_variables.scss` --- lib/generators/active_admin/assets/templates/active_admin.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/active_admin/assets/templates/active_admin.scss b/lib/generators/active_admin/assets/templates/active_admin.scss index 90ba1d475e0..d3c61f38760 100644 --- a/lib/generators/active_admin/assets/templates/active_admin.scss +++ b/lib/generators/active_admin/assets/templates/active_admin.scss @@ -1,7 +1,7 @@ // SASS variable overrides must be declared before loading up Active Admin's styles. // // To view the variables that Active Admin provides, take a look at -// `app/assets/stylesheets/active_admin/mixins/_variables.css.scss` in the +// `app/assets/stylesheets/active_admin/mixins/_variables.scss` in the // Active Admin source. // // For example, to change the sidebar width: From 67235fd0ca042a28f6b2ff9c00cb30f1659e56f5 Mon Sep 17 00:00:00 2001 From: yhirano Date: Sat, 6 Feb 2016 23:12:41 +0900 Subject: [PATCH 0045/3836] Add headline to ar.yml, es.yml ... and more --- config/locales/ar.yml | 1 + config/locales/es.yml | 1 + config/locales/id.yml | 1 + config/locales/ko.yml | 1 + config/locales/pt-BR.yml | 1 + config/locales/ru.yml | 1 + config/locales/sv-SE.yml | 1 + config/locales/uk.yml | 1 + config/locales/zh-CN.yml | 1 + config/locales/zh-TW.yml | 1 + 10 files changed, 10 insertions(+) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 2341f59d5d9..650f07f1e16 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -32,6 +32,7 @@ ar: greater_than: "أكبر من" less_than: "أقل من" search_status: + headline: "حالات البحث:" current_scope: "المجال:" current_filters: "المُرشحات الحاليّة:" no_current_filters: "بدون" diff --git a/config/locales/es.yml b/config/locales/es.yml index 2eeb8a53007..10c58bb0769 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -32,6 +32,7 @@ es: greater_than: "Mayor que" less_than: "Menor que" search_status: + headline: "Estado de la búsqueda:" current_scope: "Alcance:" current_filters: "Filtros actuales:" no_current_filters: "Ninguno" diff --git a/config/locales/id.yml b/config/locales/id.yml index 990632ddd59..64d4c3e43b5 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -32,6 +32,7 @@ id: greater_than: "Lebih besar dari" less_than: "Lebih kecil dari" search_status: + headline: "Status Pencarian:" current_scope: "Scope:" current_filters: "Filter kini:" no_current_filters: "Tidak ada" diff --git a/config/locales/ko.yml b/config/locales/ko.yml index aa1f9118e5c..5de9db56927 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -32,6 +32,7 @@ ko: greater_than: "초과" less_than: "미만" search_status: + headline: "검색 상태:" current_scope: "검색 범위:" current_filters: "적용된 필터:" no_current_filters: "현재 적용된 필터가 없습니다" diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 27cdcbc48f7..6988e398ef8 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -32,6 +32,7 @@ pt-BR: greater_than: "Maior Que" less_than: "Menor Que" search_status: + headline: "Buscou:" current_scope: "Em:" current_filters: "Filtros escolhidos:" no_current_filters: "Nenhum" diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 12b27855648..632bdd4e45a 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -32,6 +32,7 @@ ru: greater_than: "больше" less_than: "меньше" search_status: + headline: "Статус поиска:" current_scope: "Область:" current_filters: "Текущий фильтр:" no_current_filters: "Ни один" diff --git a/config/locales/sv-SE.yml b/config/locales/sv-SE.yml index 693ab9490f0..ae38abf68f5 100644 --- a/config/locales/sv-SE.yml +++ b/config/locales/sv-SE.yml @@ -32,6 +32,7 @@ greater_than: "Större än" less_than: "Mindre än" search_status: + headline: "Sök status:" current_scope: "Scope:" current_filters: "Nuvarande filter:" no_current_filters: "Inga" diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 863eaa46416..37fc9fa24f6 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -32,6 +32,7 @@ uk: greater_than: "більше" less_than: "меньше" search_status: + headline: "Статус пошуку:" current_scope: "Область:" current_filters: "Поточний фільтр:" no_current_filters: "Жоден" diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 1fcc499fb10..474387c3ebd 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -32,6 +32,7 @@ greater_than: "大于" less_than: "小于" search_status: + headline: "搜索条件:" current_scope: "搜索范围:" current_filters: "过滤条件:" no_current_filters: "无" diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index f8969952fb8..0e9c1d4d81e 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -32,6 +32,7 @@ greater_than: "大於" less_than: "小於" search_status: + headline: "搜尋條件:" current_scope: "子集:" current_filters: "目前篩選條件:" no_current_filters: "無" From c46167c683d416267f7b8ac010a977c72ca5bfc1 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 16:55:42 -0600 Subject: [PATCH 0046/3836] downgrade Cucumber https://github.com/cucumber/cucumber-ruby/issues/947 --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 84c9ac5fd85..f07f9c1401a 100644 --- a/Gemfile +++ b/Gemfile @@ -52,6 +52,7 @@ group :test do gem 'simplecov', require: false # Test coverage generator. Go to /coverage/ after running tests gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io gem 'cucumber-rails', require: false + gem 'cucumber', '1.3.20' gem 'database_cleaner' gem 'guard-rspec' gem 'jasmine' From fed57d9c211d7fc013247acd45216b8e04230bc3 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:22:52 -0600 Subject: [PATCH 0047/3836] use Github versions of gems with Rails 5 fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sprockets 4 currently doesn’t work with AA, failing to load our assets inside of a test app when it calls `@import` --- .travis.yml | 2 +- Gemfile | 31 ++++++++++++++++++++++--------- activeadmin.gemspec | 1 + lib/active_admin/dependency.rb | 2 +- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f5d57e299a..346d9cbd3d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ env: matrix: - RAILS=3.2.22 - RAILS=4.1.14 - - RAILS=master - RAILS=4.2.5 + - RAILS=master global: - JRUBY_OPTS="-J-Xmx1024m --debug" matrix: diff --git a/Gemfile b/Gemfile index f07f9c1401a..40c0a24ef2d 100644 --- a/Gemfile +++ b/Gemfile @@ -13,16 +13,27 @@ gem 'test-unit', '~> 3.0' if rails_version[0] == '3' if rails_version == 'master' gem 'arel', github: 'rails/arel' - gem 'sprockets', github: 'rails/sprockets' - gem 'sass-rails', github: 'rails/sass-rails' + # gem 'sprockets', github: 'rails/sprockets' + # gem 'sass-rails', github: 'rails/sass-rails' gem 'rack', github: 'rack/rack' - gem 'sprockets-rails', '3.0.0.beta2' + gem 'devise', github: 'plataformatec/devise' + gem 'ransack', github: 'activerecord-hackery/ransack' + gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable' + gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587' + gem 'formtastic', github: 'justinfrench/formtastic' + gem 'activemodel-serializers-xml', github: 'rails/activemodel-serializers-xml' # drapergem/draper#697 + %w[rspec-core rspec-expectations rspec-mocks rspec-rails rspec-support].each do |lib| + gem lib, github: "rspec/#{lib}" + end + gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' end # Optional dependencies gem 'cancan' -gem 'devise' -gem 'draper' +if rails_version != 'master' + gem 'devise' + gem 'draper' +end gem 'pundit' # Utility gems used in both development & test environments @@ -38,7 +49,7 @@ group :development do gem 'binding_of_caller', platforms: :mri # Retrieve the binding of a method's caller in MRI Ruby >= 1.9.2 # Performance - gem 'rack-mini-profiler' # Inline app profiler. See ?pp=help for options. + gem 'rack-mini-profiler' if rails_version != 'master' # Inline app profiler. See ?pp=help for options. gem 'flamegraph', platforms: :mri # Flamegraph visualiztion: ?pp=flamegraph # Documentation @@ -54,13 +65,15 @@ group :test do gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' gem 'database_cleaner' - gem 'guard-rspec' + gem 'guard-rspec', require: false gem 'jasmine' gem 'jslint_on_rails' gem 'launchy' gem 'rails-i18n' # Provides default i18n for many languages - gem 'rspec' - gem 'rspec-rails', '~> 3.1.0' + if rails_version != 'master' + gem 'rspec' + gem 'rspec-rails' + end gem 'i18n-spec' gem 'shoulda-matchers', '<= 2.8.0' gem 'sqlite3', platforms: :mri diff --git a/activeadmin.gemspec b/activeadmin.gemspec index a4266b10c1a..71cb96cc4dd 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -27,4 +27,5 @@ Gem::Specification.new do |s| s.add_dependency 'rails', '>= 3.2', '< 5.0' s.add_dependency 'ransack', '~> 1.3' s.add_dependency 'sass-rails' + s.add_dependency 'sprockets', '< 4' end diff --git a/lib/active_admin/dependency.rb b/lib/active_admin/dependency.rb index d0aba2f2bee..83ac5467fce 100644 --- a/lib/active_admin/dependency.rb +++ b/lib/active_admin/dependency.rb @@ -1,7 +1,7 @@ module ActiveAdmin module Dependency module Requirements - DEVISE = '~> 3.2' + DEVISE = '>= 3.2', '< 5' end # Provides a clean interface to check for gem dependencies at runtime. From c56623c0dca80ddd248fd2b82c4bd96b6c361de2 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:24:23 -0600 Subject: [PATCH 0048/3836] test app generation fixes --- script/local | 1 - tasks/test.rake | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/script/local b/script/local index 6f0cda59382..ce22c161009 100755 --- a/script/local +++ b/script/local @@ -34,7 +34,6 @@ unless File.exists? test_app_path --skip-gemfile --skip-bundle --skip-git - --skip-keeps --skip-turbolinks --skip-test-unit ] diff --git a/tasks/test.rake b/tasks/test.rake index 9f8fef46051..b8aa81fe170 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,7 +1,7 @@ desc "Creates a test rails app for the specs to run against" task :setup, :parallel do |t, opts| require 'rails/version' - if File.exists? dir = "spec/rails/rails-#{Rails::VERSION::STRING}" + if File.exists? dir = "spec/rails/rails-#{detect_rails_version}" puts "test app #{dir} already exists; skipping" else system 'mkdir -p spec/rails' @@ -10,7 +10,6 @@ task :setup, :parallel do |t, opts| --skip-gemfile --skip-bundle --skip-git - --skip-keeps --skip-turbolinks --skip-test-unit ] From 3ed7b144c62258aa8247f49e119bf9e458dcf9c7 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:26:33 -0600 Subject: [PATCH 0049/3836] RSpec now requires error messages on expectations --- spec/unit/namespace/register_page_spec.rb | 25 ++++---- spec/unit/namespace/register_resource_spec.rb | 19 +++--- spec/unit/scope_spec.rb | 61 +++++++++---------- .../download_format_links_helper_spec.rb | 18 +++--- 4 files changed, 58 insertions(+), 65 deletions(-) diff --git a/spec/unit/namespace/register_page_spec.rb b/spec/unit/namespace/register_page_spec.rb index ef679210522..1db8c1213ce 100644 --- a/spec/unit/namespace/register_page_spec.rb +++ b/spec/unit/namespace/register_page_spec.rb @@ -1,9 +1,7 @@ require 'rails_helper' describe ActiveAdmin::Namespace, "registering a page" do - let(:application){ ActiveAdmin::Application.new } - let(:namespace){ ActiveAdmin::Namespace.new(application, :admin) } let(:menu){ namespace.fetch_menu(:default) } @@ -23,17 +21,15 @@ it "should create a menu item" do expect(menu["Status"]).to be_an_instance_of(ActiveAdmin::MenuItem) end - end # context "with no configuration" + end context "with a block configuration" do it "should be evaluated in the dsl" do - expect { - namespace.register_page "Status" do - raise "Hello World" - end - }.to raise_error + expect{ |block| + namespace.register_page "Status", &block + }.to yield_control end - end # context "with a block configuration" + end describe "adding to the menu" do describe "adding as a top level item" do @@ -44,7 +40,7 @@ it "should add a new menu item" do expect(menu['Status']).to_not be_nil end - end # describe "adding as a top level item" + end describe "adding as a child" do before do @@ -52,13 +48,15 @@ menu parent: 'Extra' end end + it "should generate the parent menu item" do expect( menu['Extra']).to_not be_nil end + it "should generate its own child item" do expect(menu['Extra']['Status']).to_not be_nil end - end # describe "adding as a child" + end describe "disabling the menu" do before do @@ -66,9 +64,10 @@ menu false end end + it "should not create a menu item" do expect(menu["Status"]).to be_nil end - end # describe "disabling the menu" - end # describe "adding to the menu" + end + end end diff --git a/spec/unit/namespace/register_resource_spec.rb b/spec/unit/namespace/register_resource_spec.rb index 9a427e61e42..63aec588c4c 100644 --- a/spec/unit/namespace/register_resource_spec.rb +++ b/spec/unit/namespace/register_resource_spec.rb @@ -4,41 +4,40 @@ # Specifically, the dashboard is already defined. describe ActiveAdmin::Namespace, "registering a resource" do - let(:application){ ActiveAdmin::Application.new } - let(:namespace){ ActiveAdmin::Namespace.new(application, :admin) } - let(:menu){ namespace.fetch_menu(:default) } context "with no configuration" do before do namespace.register Category end + it "should store the namespaced registered configuration" do expect(namespace.resources.keys).to include('Category') end + it "should create a new controller in the default namespace" do expect(defined?(Admin::CategoriesController)).to be_truthy end + skip "should not create the dashboard controller" do defined?(Admin::DashboardController).to_not be_truthy end + it "should create a menu item" do expect(menu["Categories"]).to be_a ActiveAdmin::MenuItem expect(menu["Categories"].instance_variable_get(:@url)).to be_a Proc end - end # context "with no configuration" + end context "with a block configuration" do it "should be evaluated in the dsl" do - expect { - namespace.register Category do - raise "Hello World" - end - }.to raise_error + expect{ |block| + namespace.register Category, &block + }.to yield_control end - end # context "with a block configuration" + end context "with a resource that's namespaced" do before do diff --git a/spec/unit/scope_spec.rb b/spec/unit/scope_spec.rb index d944e06f0f4..69a6304f2fb 100644 --- a/spec/unit/scope_spec.rb +++ b/spec/unit/scope_spec.rb @@ -6,130 +6,131 @@ subject{ scope } context "when just a scope method" do - let(:scope) { ActiveAdmin::Scope.new :published } + let(:scope) { ActiveAdmin::Scope.new :published } describe '#name' do subject { super().name } - it { is_expected.to eq("Published")} + it { is_expected.to eq("Published")} end describe '#id' do subject { super().id } - it { is_expected.to eq("published")} + it { is_expected.to eq("published")} end describe '#scope_method' do subject { super().scope_method } - it { is_expected.to eq(:published) } + it { is_expected.to eq(:published) } end end context "when scope method is :all" do - let(:scope) { ActiveAdmin::Scope.new :all } + let(:scope) { ActiveAdmin::Scope.new :all } describe '#name' do subject { super().name } - it { is_expected.to eq("All")} + it { is_expected.to eq("All")} end describe '#id' do subject { super().id } - it { is_expected.to eq("all")} + it { is_expected.to eq("all")} end # :all does not return a chain but an array of active record # instances. We set the scope_method to nil then. describe '#scope_method' do subject { super().scope_method } - it { is_expected.to eq(nil) } + it { is_expected.to eq(nil) } end describe '#scope_block' do subject { super().scope_block } - it { is_expected.to eq(nil) } + it { is_expected.to eq(nil) } end end context 'when a name and scope method is :all' do - let(:scope) { ActiveAdmin::Scope.new 'Tous', :all } + let(:scope) { ActiveAdmin::Scope.new 'Tous', :all } describe '#name' do subject { super().name } - it { is_expected.to eq 'Tous' } + it { is_expected.to eq 'Tous' } end describe '#scope_method' do subject { super().scope_method } - it { is_expected.to be_nil } + it { is_expected.to be_nil } end describe '#scope_block' do subject { super().scope_block } - it { is_expected.to be_nil } + it { is_expected.to be_nil } end end context "when a name and scope method" do - let(:scope) { ActiveAdmin::Scope.new "With API Access", :with_api_access } + let(:scope) { ActiveAdmin::Scope.new "With API Access", :with_api_access } describe '#name' do subject { super().name } - it { is_expected.to eq("With API Access")} + it { is_expected.to eq("With API Access")} end describe '#id' do subject { super().id } - it { is_expected.to eq("with_api_access")} + it { is_expected.to eq("with_api_access")} end describe '#scope_method' do subject { super().scope_method } - it { is_expected.to eq(:with_api_access) } + it { is_expected.to eq(:with_api_access) } end end context "when a name and scope block" do - let(:scope) { ActiveAdmin::Scope.new("My Scope"){|s| s } } + let(:scope) { ActiveAdmin::Scope.new("My Scope"){|s| s } } describe '#name' do subject { super().name } - it { is_expected.to eq("My Scope")} + it { is_expected.to eq("My Scope")} end describe '#id' do subject { super().id } - it { is_expected.to eq("my_scope")} + it { is_expected.to eq("my_scope")} end describe '#scope_method' do subject { super().scope_method } - it { is_expected.to eq(nil) } + it { is_expected.to eq(nil) } end describe '#scope_block' do subject { super().scope_block } - it { is_expected.to be_a(Proc)} + it { is_expected.to be_a(Proc)} end end context "when a name has a space and lowercase" do - let(:scope) { ActiveAdmin::Scope.new("my scope") } + let(:scope) { ActiveAdmin::Scope.new("my scope") } describe '#name' do subject { super().name } - it { is_expected.to eq("my scope")} + it { is_expected.to eq("my scope")} end describe '#id' do subject { super().id } - it { is_expected.to eq("my_scope")} + it { is_expected.to eq("my_scope")} end end context "with a proc as the label" do it "should raise an exception if a second argument isn't provided" do - expect{ ActiveAdmin::Scope.new proc{ Date.today.strftime '%A' } - }.to raise_error + expect{ + ActiveAdmin::Scope.new proc{ Date.today.strftime '%A' } + }.to raise_error 'A string/symbol is required as the second argument if your label is a proc.' end it "should properly render the proc" do @@ -141,7 +142,6 @@ end # describe "creating a scope" describe "#display_if_block" do - it "should return true by default" do scope = ActiveAdmin::Scope.new(:default) expect(scope.display_if_block.call).to eq true @@ -151,11 +151,9 @@ scope = ActiveAdmin::Scope.new(:with_block, nil, if: proc{ false }) expect(scope.display_if_block.call).to eq false end - end describe "#default" do - it "should accept a boolean" do scope = ActiveAdmin::Scope.new(:method, nil, default: true) expect(scope.default_block).to eq true @@ -170,11 +168,9 @@ scope = ActiveAdmin::Scope.new(:with_block, nil, default: proc{ true }) expect(scope.default_block.call).to eq true end - end describe "show_count" do - it "should allow setting of show_count to prevent showing counts" do scope = ActiveAdmin::Scope.new(:default, nil, show_count: false) expect(scope.show_count).to eq false @@ -184,7 +180,6 @@ scope = ActiveAdmin::Scope.new(:default) expect(scope.show_count).to eq true end - end end diff --git a/spec/unit/view_helpers/download_format_links_helper_spec.rb b/spec/unit/view_helpers/download_format_links_helper_spec.rb index 9181d0d4ccc..0a761bc5c66 100644 --- a/spec/unit/view_helpers/download_format_links_helper_spec.rb +++ b/spec/unit/view_helpers/download_format_links_helper_spec.rb @@ -1,38 +1,38 @@ require 'rails_helper' describe ActiveAdmin::ViewHelpers::DownloadFormatLinksHelper do - describe "class methods" do before :all do - begin # The mime type to be used in respond_to |format| style web-services in rails Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx rescue NameError puts "Mime module not defined. Skipping registration of xlsx" end + end - class Foo + subject do + Class.new do include ActiveAdmin::ViewHelpers::DownloadFormatLinksHelper end end it "extends the class to add a formats class method that returns the default formats." do - expect(Foo.formats).to eq [:csv, :xml, :json] + expect(subject.formats).to eq [:csv, :xml, :json] end it "does not let you alter the formats array directly" do - Foo.formats << :xlsx - expect(Foo.formats).to eq [:csv, :xml, :json] + subject.formats << :xlsx + expect(subject.formats).to eq [:csv, :xml, :json] end it "allows us to add new formats" do - Foo.add_format :xlsx - expect(Foo.formats).to eq [:csv, :xml, :json, :xlsx] + subject.add_format :xlsx + expect(subject.formats).to eq [:csv, :xml, :json, :xlsx] end it "raises an exception if you provide an unregisterd mime type extension" do - expect{ Foo.add_format :hoge }.to raise_error + expect{ subject.add_format :hoge }.to raise_error 'Please register the hoge mime type with `Mime::Type.register`' end end From 8138b6b2ac1fe7be6f15319b3c726b84aaa182a5 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:27:34 -0600 Subject: [PATCH 0050/3836] RSpec methods are no longer available globally --- spec/unit/form_builder_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 9640b4dcbbb..7c774d444bb 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -563,8 +563,11 @@ def user describe "with allow destroy" do context "with an existing post" do let :body do + s = self build_form({url: '/categories'}, Category.new) do |f| - allow(f.object.posts.build).to receive(:new_record?).and_return(false) + s.instance_exec do + allow(f.object.posts.build).to receive(:new_record?).and_return(false) + end f.has_many :posts, allow_destroy: true do |p| p.input :title end From 3c689a15f56aea56f69766a025d4d8ee0f2c3684 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:28:33 -0600 Subject: [PATCH 0051/3836] use request.user_agent --- lib/active_admin/views/pages/base.rb | 2 +- spec/unit/views/components/unsupported_browser_spec.rb | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/active_admin/views/pages/base.rb b/lib/active_admin/views/pages/base.rb index b40d678fd36..45b0ba0e549 100644 --- a/lib/active_admin/views/pages/base.rb +++ b/lib/active_admin/views/pages/base.rb @@ -56,7 +56,7 @@ def build_page end def build_unsupported_browser - if active_admin_namespace.unsupported_browser_matcher =~ env["HTTP_USER_AGENT"] + if active_admin_namespace.unsupported_browser_matcher =~ request.user_agent insert_tag view_factory.unsupported_browser end end diff --git a/spec/unit/views/components/unsupported_browser_spec.rb b/spec/unit/views/components/unsupported_browser_spec.rb index bd259573e64..2c16ba22959 100644 --- a/spec/unit/views/components/unsupported_browser_spec.rb +++ b/spec/unit/views/components/unsupported_browser_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe ActiveAdmin::Views::UnsupportedBrowser do - let(:helpers){ mock_action_view } let(:namespace) { double :namespace, unsupported_browser_matcher: /MSIE [1-8]\.0/ } let(:component) { double :unsupported_browser_component } @@ -21,27 +20,22 @@ def build_panel describe "ActiveAdmin::Views::Pages::Base behavior" do context "when the reqex match" do - it "should build the unsupported browser panel" do expect(base).to receive(:active_admin_namespace).and_return(namespace) - expect(base).to receive(:env).and_return({ "HTTP_USER_AGENT" => "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0)" }) + expect(base).to receive_message_chain(:request, :user_agent).and_return("Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0)") expect(base).to receive(:view_factory).and_return(view_factory) expect(base).to receive(:insert_tag).with(component) base.send(:build_unsupported_browser) end - end context "when the regex not match" do - it "should not build the unsupported browser panel" do expect(base).to receive(:active_admin_namespace).and_return(namespace) - expect(base).to receive(:env).and_return({ "HTTP_USER_AGENT" => "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)" }) + expect(base).to receive_message_chain(:request, :user_agent).and_return("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)") expect(base).to receive(:insert_tag).never base.send(:build_unsupported_browser) end - end end - end From efd638726c154e0cb90fb40943c8e9d49c726d60 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:29:36 -0600 Subject: [PATCH 0052/3836] `render text:` is deprecated --- lib/active_admin/base_controller/authorization.rb | 2 +- spec/unit/authorization/index_overriding_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/base_controller/authorization.rb b/lib/active_admin/base_controller/authorization.rb index de298cc5275..2e9c0ec4ddc 100644 --- a/lib/active_admin/base_controller/authorization.rb +++ b/lib/active_admin/base_controller/authorization.rb @@ -113,7 +113,7 @@ def rescue_active_admin_access_denied(exception) redirect_backwards_or_to_root end - format.csv { render text: error, status: :unauthorized } + format.csv { render body: error, status: :unauthorized } format.json { render json: { error: error }, status: :unauthorized } format.xml { render xml: "#{error}", status: :unauthorized } end diff --git a/spec/unit/authorization/index_overriding_spec.rb b/spec/unit/authorization/index_overriding_spec.rb index cfcc982a9c4..f1baf6b50af 100644 --- a/spec/unit/authorization/index_overriding_spec.rb +++ b/spec/unit/authorization/index_overriding_spec.rb @@ -5,7 +5,7 @@ controller.instance_eval do def index super do - render text: 'Rendered from passed block' and return + render body: 'Rendered from passed block' and return end end end From 8ec21eef51f548de56e6a250a40d064f81667db9 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:30:22 -0600 Subject: [PATCH 0053/3836] callstack objects are no longer arrays of strings --- features/support/env.rb | 2 +- spec/rails_helper.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/support/env.rb b/features/support/env.rb index 93c9b0cca81..ac3c134d4cf 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -124,7 +124,7 @@ # This would set `behavior = :raise`, but that wasn't added until Rails 4. ActiveSupport::Deprecation.behavior = -> message, callstack do e = StandardError.new message - e.set_backtrace callstack + e.set_backtrace callstack.map(&:to_s) raise e end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 0e66ba9c85d..297133c800b 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -147,7 +147,7 @@ def with_translation(translation) # This would set `behavior = :raise`, but that wasn't added until Rails 4. ActiveSupport::Deprecation.behavior = -> message, callstack do e = StandardError.new message - e.set_backtrace callstack + e.set_backtrace callstack.map(&:to_s) raise e end From 64ca9b43fb1737323a78ddf6d0fff34637c80e80 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:32:30 -0600 Subject: [PATCH 0054/3836] stop using hacks to test that controller actions are called just call them instead, by actually hitting the controller via its public API this change was necessary because the internal callbacks object has changed quite a bit --- spec/unit/action_builder_spec.rb | 112 +++++++++--------- .../unit/resource_controller/sidebars_spec.rb | 39 +++--- 2 files changed, 72 insertions(+), 79 deletions(-) diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb index 37b8a2b51e4..a46a6bd9dd5 100644 --- a/spec/unit/action_builder_spec.rb +++ b/spec/unit/action_builder_spec.rb @@ -1,20 +1,24 @@ require 'rails_helper' -describe 'defining new actions from registration blocks' do +describe 'defining actions from registration blocks', type: :controller do + let(:klass){ Admin::PostsController } + render_views # https://github.com/rspec/rspec-rails/issues/860 - let(:controller){ Admin::PostsController } + before do + @controller = klass.new + end - describe "generating a new member action" do + describe 'creates a member action' do before do action! reload_routes! end after(:each) do - controller.clear_member_actions! + klass.clear_member_actions! end - context "with a block" do + context 'with a block' do let(:action!) do ActiveAdmin.register Post do member_action :comment do @@ -23,51 +27,59 @@ end end - it "should create a new public instance method" do - expect(controller.public_instance_methods.collect(&:to_s)).to include("comment") + it 'should create a new public instance method' do + expect(klass.public_instance_methods.collect(&:to_s)).to include('comment') end - it "should add itself to the member actions config" do - expect(controller.active_admin_config.member_actions.size).to eq 1 + + it 'should add itself to the member actions config' do + expect(klass.active_admin_config.member_actions.size).to eq 1 end - it "should create a new named route" do - expect(Rails.application.routes.url_helpers.methods.collect(&:to_s)).to include("comment_admin_post_path") + + it 'should create a new named route' do + expect(Rails.application.routes.url_helpers.methods.collect(&:to_s)).to include('comment_admin_post_path') end end - context "without a block" do + context 'without a block' do let(:action!) do ActiveAdmin.register Post do member_action :comment end end - it "should still generate a new empty action" do - expect(controller.public_instance_methods.collect(&:to_s)).to include("comment") + + it 'should still generate a new empty action' do + expect(klass.public_instance_methods.collect(&:to_s)).to include('comment') end end - context "with :title" do + context 'with :title' do let(:action!) do ActiveAdmin.register Post do - member_action :comment, title: "My Awesome Comment" + member_action :comment, title: 'My Awesome Comment' do + render json: {a: 2} + end end end - subject { find_before_filter controller, :comment } + it 'sets the page title' do + get :comment, params: {id: 1} - it { is_expected.to set_page_title_to "My Awesome Comment", for: controller } + expect(controller.instance_variable_get(:@page_title)).to eq 'My Awesome Comment' + end end end - describe "generate a new collection action" do + describe 'creates a collection action' do before do action! reload_routes! end + after(:each) do - controller.clear_collection_actions! + klass.clear_collection_actions! end - context "with a block" do + context 'with a block' do let(:action!) do ActiveAdmin.register Post do collection_action :comments do @@ -75,58 +87,46 @@ end end end - it "should create a new public instance method" do - expect(controller.public_instance_methods.collect(&:to_s)).to include("comments") + + it 'should create a public instance method' do + expect(klass.public_instance_methods.collect(&:to_s)).to include('comments') end - it "should add itself to the member actions config" do - expect(controller.active_admin_config.collection_actions.size).to eq 1 + + it 'should add itself to the member actions config' do + expect(klass.active_admin_config.collection_actions.size).to eq 1 end - it "should create a new named route" do - expect(Rails.application.routes.url_helpers.methods.collect(&:to_s)).to include("comments_admin_posts_path") + + it 'should create a named route' do + expect(Rails.application.routes.url_helpers.methods.collect(&:to_s)).to include('comments_admin_posts_path') end end - context "without a block" do + + context 'without a block' do let(:action!) do ActiveAdmin.register Post do collection_action :comments end end - it "should still generate a new empty action" do - expect(controller.public_instance_methods.collect(&:to_s)).to include("comments") + + it 'should still generate a new empty action' do + expect(klass.public_instance_methods.collect(&:to_s)).to include('comments') end end - context "with :title" do + + context 'with :title' do let(:action!) do ActiveAdmin.register Post do - collection_action :comments, title: "My Awesome Comments" + collection_action :comments, title: 'My Awesome Comments' do + render json: {a: 2} + end end end - subject { find_before_filter controller, :comments } - - it { is_expected.to set_page_title_to "My Awesome Comments", for: controller } - end - end - - def find_before_filter(controller, action) - finder = if ActiveAdmin::Dependency.rails? '>= 4.1.0' - ->c { c.kind == :before && c.instance_variable_get(:@if) == ["action_name == '#{action}'"] } - else - ->c { c.kind == :before && c.options[:only] == [action] } - end - - controller._process_action_callbacks.detect &finder - end + it 'sets the page title' do + get :comments - RSpec::Matchers.define :set_page_title_to do |expected, options| - match do |filter| - filter.raw_filter.call - @actual = options[:for].instance_variable_get(:@page_title) - expect(@actual).to eq expected - end - - failure_message do |filter| - message = "expected before_filter to set the @page_title to '#{expected}', but was '#{@actual}'" + expect(controller.instance_variable_get(:@page_title)).to eq 'My Awesome Comments' + end end end end diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index d5f362ffe2c..41ac52cf822 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -1,16 +1,24 @@ require 'rails_helper' -describe ActiveAdmin::ResourceController::Sidebars do - let(:controller){ Admin::PostsController } +describe ActiveAdmin::ResourceController::Sidebars, type: :controller do + let(:klass){ Admin::PostsController } + render_views # https://github.com/rspec/rspec-rails/issues/860 + + before do + @controller = klass.new + end context 'without before_filter' do before do ActiveAdmin.register Post + reload_routes! end - subject { find_before_filter controller, :skip_sidebar! } + it 'does not set @skip_sidebar' do + get :index - it { is_expected.to set_skip_sidebar_to nil, for: controller } + expect(controller.instance_variable_get(:@skip_sidebar)).to eq nil + end end describe '#skip_sidebar!' do @@ -18,28 +26,13 @@ ActiveAdmin.register Post do before_filter :skip_sidebar! end + reload_routes! end - subject { find_before_filter controller, :skip_sidebar! } - - it { is_expected.to set_skip_sidebar_to true, for: controller } - end - - def find_before_filter(controller, filter) - #raise controller._process_action_callbacks.map(&:filter).inspect - controller._process_action_callbacks.detect { |f| f.raw_filter == filter.to_sym } - end - - RSpec::Matchers.define :set_skip_sidebar_to do |expected, options| - match do |filter| - object = options[:for].new - object.send filter.raw_filter if filter - @actual = object.instance_variable_get(:@skip_sidebar) - expect(@actual).to eq expected - end + it 'works' do + get :index - failure_message do |filter| - message = "expected before_filter to set @skip_sidebar to '#{expected}', but was '#{@actual}'" + expect(controller.instance_variable_get(:@skip_sidebar)).to eq true end end end From df7fe4de20030cf0e41b6fdd77e9e80d362746d2 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:34:19 -0600 Subject: [PATCH 0055/3836] deal with parameterize API change --- lib/active_admin/dependency.rb | 49 +++++++++++++++++++ lib/active_admin/scope.rb | 5 +- .../views/components/attributes_table.rb | 2 +- .../views/components/table_for.rb | 2 +- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/lib/active_admin/dependency.rb b/lib/active_admin/dependency.rb index 83ac5467fce..f3e3f17098f 100644 --- a/lib/active_admin/dependency.rb +++ b/lib/active_admin/dependency.rb @@ -90,6 +90,55 @@ def inspect info = spec ? "#{spec.name} #{spec.version}" : '(missing)' "" end + + def adapter + @adapter ||= Adapter.const_get(@name.camelize).new self + end + + def method_missing(method, *args, &block) + if respond_to_missing?(method) + adapter.send method, *args, &block + else + super + end + end + + def respond_to_missing?(method, include_private = false) + adapter.respond_to?(method) || super + rescue NameError + # 🐾 + end end + + # Dependency adapters provide an easy way to wrap the conditional logic + # necessary to support multiple versions of a gem. + # + # ActiveAdmin::Dependency.rails.adapter.parameterize 'a b' + # => 'a_b' + # + # ActiveAdmin::Dependency.rails.parameterize 'a b' + # => 'a_b' + # + # ActiveAdmin::Dependency.devise.adapter + # -> NameError: uninitialized constant ActiveAdmin::Dependency::Adapter::Devise + # + module Adapter + class Base + def initialize(version) + @version = version + end + end + + class Rails < Base + def parameterize(string) + if @version >= '5.beta' + string.parameterize separator: '_' + else + string.parameterize '_' + end + end + end + end + end end diff --git a/lib/active_admin/scope.rb b/lib/active_admin/scope.rb index 9251c370813..8f6cda832d1 100644 --- a/lib/active_admin/scope.rb +++ b/lib/active_admin/scope.rb @@ -29,10 +29,10 @@ def initialize(name, method = nil, options = {}, &block) if name.is_a? Proc raise "A string/symbol is required as the second argument if your label is a proc." unless method - @id = method.to_s.parameterize("_") + @id = ActiveAdmin::Dependency.rails.parameterize method.to_s else @scope_method ||= name.to_sym - @id = name.to_s.parameterize("_") + @id = ActiveAdmin::Dependency.rails.parameterize name.to_s end @scope_method = nil if @scope_method == :all @@ -41,7 +41,6 @@ def initialize(name, method = nil, options = {}, &block) @show_count = options.fetch(:show_count, true) @display_if_block = options[:if] || proc{ true } @default_block = options[:default] || proc{ false } - end def name diff --git a/lib/active_admin/views/components/attributes_table.rb b/lib/active_admin/views/components/attributes_table.rb index 2c1d15a052e..7a80361ca32 100644 --- a/lib/active_admin/views/components/attributes_table.rb +++ b/lib/active_admin/views/components/attributes_table.rb @@ -26,7 +26,7 @@ def row(*args, &block) if options[:class] classes << options[:class] elsif title.present? - classes << "row-#{title.to_s.parameterize('_')}" + classes << "row-#{ActiveAdmin::Dependency.rails.parameterize(title.to_s)}" end options[:class] = classes.join(' ') diff --git a/lib/active_admin/views/components/table_for.rb b/lib/active_admin/views/components/table_for.rb index 6eaaaf9c760..9f5a068c551 100644 --- a/lib/active_admin/views/components/table_for.rb +++ b/lib/active_admin/views/components/table_for.rb @@ -164,7 +164,7 @@ def initialize(*args, &block) if @options.has_key?(:class) html_classes << @options.delete(:class) elsif @title.present? - html_classes << "col-#{@title.to_s.parameterize('_')}" + html_classes << "col-#{ActiveAdmin::Dependency.rails.parameterize(@title.to_s)}" end @html_class = html_classes.join(' ') @data = args[1] || args[0] From 1f7dc842f50361f9ac58328cf76937c3a1a60669 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 12:43:48 -0600 Subject: [PATCH 0056/3836] implement *_filter callbacks that delegate to *_action While pretty complicated, this implementation should allow us to support Rails 3.2 to Rails 5. Any callback inside of the controller itself still requires an if condition to determine which method to call, since our methods are defined on the resource object, which wraps the controller. --- lib/active_admin/base_controller.rb | 9 +++++++-- lib/active_admin/base_controller/menu.rb | 6 +++++- lib/active_admin/page_controller.rb | 6 +++++- lib/active_admin/resource_dsl.rb | 24 +++++++++++++++--------- spec/unit/resource_spec.rb | 16 +++++++++------- 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/lib/active_admin/base_controller.rb b/lib/active_admin/base_controller.rb index 50be2163c62..2a8bc77300a 100644 --- a/lib/active_admin/base_controller.rb +++ b/lib/active_admin/base_controller.rb @@ -10,8 +10,13 @@ class BaseController < ::InheritedResources::Base layout :determine_active_admin_layout - before_filter :only_render_implemented_actions - before_filter :authenticate_active_admin_user + if ActiveAdmin::Dependency.rails >= 4 + before_action :only_render_implemented_actions + before_action :authenticate_active_admin_user + else + before_filter :only_render_implemented_actions + before_filter :authenticate_active_admin_user + end class << self # Ensure that this method is available for the DSL diff --git a/lib/active_admin/base_controller/menu.rb b/lib/active_admin/base_controller/menu.rb index 52b7a49b0a2..07c3d37b208 100644 --- a/lib/active_admin/base_controller/menu.rb +++ b/lib/active_admin/base_controller/menu.rb @@ -4,7 +4,11 @@ module Menu extend ActiveSupport::Concern included do - before_filter :set_current_tab + if ActiveAdmin::Dependency.rails >= 4 + before_action :set_current_tab + else + before_filter :set_current_tab + end helper_method :current_menu end diff --git a/lib/active_admin/page_controller.rb b/lib/active_admin/page_controller.rb index 4048d313838..7150ce86083 100644 --- a/lib/active_admin/page_controller.rb +++ b/lib/active_admin/page_controller.rb @@ -8,7 +8,11 @@ class PageController < BaseController actions :index - before_filter :authorize_access! + if ActiveAdmin::Dependency.rails >= 4 + before_action :authorize_access! + else + before_filter :authorize_access! + end def index(options={}, &block) render "active_admin/page/index" diff --git a/lib/active_admin/resource_dsl.rb b/lib/active_admin/resource_dsl.rb index 28647d4553b..289e4580783 100644 --- a/lib/active_admin/resource_dsl.rb +++ b/lib/active_admin/resource_dsl.rb @@ -116,7 +116,8 @@ def action(set, name, options = {}, &block) title = options.delete(:title) controller do - before_filter(only: [name]) { @page_title = title } if title + callback = ActiveAdmin::Dependency.rails >= 4 ? :before_action : :before_filter + send(callback, only: [name]) { @page_title = title } if title define_method(name, &block || Proc.new{}) end end @@ -159,14 +160,19 @@ def collection_action(name, options = {}, &block) delegate :before_save, :after_save, to: :controller delegate :before_destroy, :after_destroy, to: :controller - # Standard rails filters - delegate :before_filter, :skip_before_filter, to: :controller - delegate :after_filter, :skip_after_filter, to: :controller - delegate :around_filter, :skip_filter, to: :controller - if Rails::VERSION::MAJOR == 4 - delegate :before_action, :skip_before_action, to: :controller - delegate :after_action, :skip_after_action, to: :controller - delegate :around_action, :skip_action, to: :controller + # This code defines both *_filter and *_action for Rails 3.2 to Rails 5. + actions = [ + :before, :skip_before, + :after, :skip_after, + :around, :skip + ] + destination = ActiveAdmin::Dependency.rails >= 4 ? :action : :filter + [:action, :filter].each do |name| + actions.each do |action| + define_method "#{action}_#{name}" do |*args, &block| + controller.public_send "#{action}_#{destination}", *args, &block + end + end end # Specify which actions to create in the controller diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index 4b62bbe2d49..ad699e5e119 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -304,22 +304,24 @@ def method_missing(name, *args, &block) :before_filter, :skip_before_filter, :after_filter, :skip_after_filter, :around_filter, :skip_filter - ].each do |filter| - it "delegates #{filter}" do - expect(resource.send(filter)).to eq "called #{filter}" + ].each do |method| + it "delegates #{method}" do + expected = method.to_s.dup + expected.sub! 'filter', 'action' if ActiveAdmin::Dependency.rails >= 4 + expect(resource.send(method)).to eq "called #{expected}" end end end - if Rails::VERSION::MAJOR == 4 + if ActiveAdmin::Dependency.rails >= 4 context "actions" do [ :before_action, :skip_before_action, :after_action, :skip_after_action, :around_action, :skip_action - ].each do |action| - it "delegates #{action}" do - expect(resource.send(action)).to eq "called #{action}" + ].each do |method| + it "delegates #{method}" do + expect(resource.send(method)).to eq "called #{method}" end end end From d5ebd043c136fda0148f65190ed0381e6d9739e1 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 13:40:11 -0600 Subject: [PATCH 0057/3836] fix controller test for Rails < 5 Controller tests now have to scope query params inside of a params key (it also now lets you pass session variables & headers). This test had been updated with the new syntax, but we still need to support Rails 4. --- spec/unit/action_builder_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb index a46a6bd9dd5..ddd38f1be37 100644 --- a/spec/unit/action_builder_spec.rb +++ b/spec/unit/action_builder_spec.rb @@ -62,7 +62,9 @@ end it 'sets the page title' do - get :comment, params: {id: 1} + params = {id: 1} + params = {params: params} if ActiveAdmin::Dependency.rails > 4 + get :comment, params expect(controller.instance_variable_get(:@page_title)).to eq 'My Awesome Comment' end From 8d2b79f7ca7be39b8733d329e13bc1982240ea38 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 13:51:19 -0600 Subject: [PATCH 0058/3836] fix permitted params conditionals for Rails 5 --- features/development_reloading.feature | 2 +- features/edit_page.feature | 8 ++++---- features/new_page.feature | 8 ++++---- features/renamed_resource.feature | 2 +- features/sti_resource.feature | 4 ++-- lib/generators/active_admin/resource/templates/admin.rb | 2 +- spec/support/rails_template.rb | 2 +- spec/support/templates/admin/stores.rb | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/features/development_reloading.feature b/features/development_reloading.feature index 56a2eae2fb0..cc087784a15 100644 --- a/features/development_reloading.feature +++ b/features/development_reloading.feature @@ -12,7 +12,7 @@ Feature: Development Reloading When "app/admin/posts.rb" contains: """ ActiveAdmin.register Post do - if Rails::VERSION::MAJOR == 4 + if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, :body, :position, :published_at, :starred end diff --git a/features/edit_page.feature b/features/edit_page.feature index 704c8beb844..1cb73a22e7f 100644 --- a/features/edit_page.feature +++ b/features/edit_page.feature @@ -10,7 +10,7 @@ Feature: Edit Page Given a configuration of: """ ActiveAdmin.register Post do - if Rails::VERSION::MAJOR == 4 + if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, :body, :position, :published_at, :starred end @@ -34,7 +34,7 @@ Feature: Edit Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR == 4 + permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 form do |f| f.inputs "Your Post" do @@ -63,7 +63,7 @@ Feature: Edit Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR == 4 + permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 form :html => {} do |f| f.inputs "Your Post" do @@ -102,7 +102,7 @@ Feature: Edit Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR == 4 + permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 form :partial => "form" end diff --git a/features/new_page.feature b/features/new_page.feature index 08162415b01..a10a384405e 100644 --- a/features/new_page.feature +++ b/features/new_page.feature @@ -9,7 +9,7 @@ Feature: New Page Given a configuration of: """ ActiveAdmin.register Post do - if Rails::VERSION::MAJOR == 4 + if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, :body, :position, :published_at, :starred end @@ -34,7 +34,7 @@ Feature: New Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR == 4 + permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 form do |f| f.inputs "Your Post" do @@ -70,7 +70,7 @@ Feature: New Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR == 4 + permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 form :partial => "form" end @@ -87,7 +87,7 @@ Feature: New Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR == 4 + permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 form do |f| f.inputs "Your Post" do diff --git a/features/renamed_resource.feature b/features/renamed_resource.feature index 9ce8c065ac2..e6fa6ff7b48 100644 --- a/features/renamed_resource.feature +++ b/features/renamed_resource.feature @@ -9,7 +9,7 @@ Feature: Renamed Resource Given a configuration of: """ ActiveAdmin.register Blog::Post, as: 'Post' do - if Rails::VERSION::MAJOR == 4 + if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, :body, :position, :published_at, :starred end diff --git a/features/sti_resource.feature b/features/sti_resource.feature index e809ccb9229..556943e9e11 100644 --- a/features/sti_resource.feature +++ b/features/sti_resource.feature @@ -7,10 +7,10 @@ Feature: STI Resource And a configuration of: """ ActiveAdmin.register Publisher do - permit_params :first_name, :last_name, :username, :age if Rails::VERSION::MAJOR == 4 + permit_params :first_name, :last_name, :username, :age if Rails::VERSION::MAJOR >= 4 end ActiveAdmin.register User do - permit_params :first_name, :last_name, :username, :age if Rails::VERSION::MAJOR == 4 + permit_params :first_name, :last_name, :username, :age if Rails::VERSION::MAJOR >= 4 end """ diff --git a/lib/generators/active_admin/resource/templates/admin.rb b/lib/generators/active_admin/resource/templates/admin.rb index 9f300b7693c..9bc592df8fa 100644 --- a/lib/generators/active_admin/resource/templates/admin.rb +++ b/lib/generators/active_admin/resource/templates/admin.rb @@ -1,5 +1,5 @@ ActiveAdmin.register <%= class_name %> do -<% if Rails::VERSION::MAJOR == 4 || defined?(ActionController::StrongParameters) %> +<% if Rails::VERSION::MAJOR >= 4 || defined?(ActionController::StrongParameters) %> # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters # diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 1a8f428bb1a..bf7f3a55a9b 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -136,7 +136,7 @@ class Tagging < ActiveRecord::Base # Force strong parameters to raise exceptions inject_into_file 'config/application.rb', <<-RUBY, after: 'class Application < Rails::Application' - config.action_controller.action_on_unpermitted_parameters = :raise if Rails::VERSION::MAJOR == 4 + config.action_controller.action_on_unpermitted_parameters = :raise if Rails::VERSION::MAJOR >= 4 RUBY diff --git a/spec/support/templates/admin/stores.rb b/spec/support/templates/admin/stores.rb index daddb7234b3..aa1840b03c9 100644 --- a/spec/support/templates/admin/stores.rb +++ b/spec/support/templates/admin/stores.rb @@ -1,6 +1,6 @@ ActiveAdmin.register Store do - if Rails::VERSION::MAJOR == 4 + if Rails::VERSION::MAJOR >= 4 permit_params :name end From 5a47b78d4db7317a2943e43b7af8b119c873d7ad Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 14:34:00 -0600 Subject: [PATCH 0059/3836] use database_cleaner from Github --- Gemfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 40c0a24ef2d..0cf57ebd114 100644 --- a/Gemfile +++ b/Gemfile @@ -26,6 +26,7 @@ if rails_version == 'master' gem lib, github: "rspec/#{lib}" end gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' + gem 'database_cleaner', github: 'pschambacher/database_cleaner', branch: 'rails5.0', ref: '8dd9fa4' end # Optional dependencies @@ -64,7 +65,7 @@ group :test do gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' - gem 'database_cleaner' + gem 'database_cleaner' if rails_version != 'master' gem 'guard-rspec', require: false gem 'jasmine' gem 'jslint_on_rails' From 169266636363278c903dc87965f6501778c2fa05 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 14:34:48 -0600 Subject: [PATCH 0060/3836] fix transactional tests deprecation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit & call puts for deprecation in Cucumber, because they sometimes won’t be printed and you’ll be left with a failed test but no failure message --- features/support/env.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/features/support/env.rb b/features/support/env.rb index ac3c134d4cf..b31dcb39fb7 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -81,7 +81,12 @@ # after each scenario, which can lead to hard-to-debug failures in # subsequent scenarios. If you do this, we recommend you create a Before # block that will explicitly put your database in a known state. -Cucumber::Rails::World.use_transactional_fixtures = false +if ActiveAdmin::Dependency.rails5? + Cucumber::Rails::World.use_transactional_tests = true +else + Cucumber::Rails::World.use_transactional_fixtures = true +end + # How to clean your database when transactions are turned off. See # http://github.com/bmabey/database_cleaner for more info. if defined?(ActiveRecord::Base) @@ -125,6 +130,7 @@ ActiveSupport::Deprecation.behavior = -> message, callstack do e = StandardError.new message e.set_backtrace callstack.map(&:to_s) + puts e raise e end From e4e77b0c8d9e9927ad046261cf7d40aa719e7688 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 14:35:16 -0600 Subject: [PATCH 0061/3836] uniq -> distinct --- lib/active_admin/inputs/filters/select_input.rb | 3 ++- spec/unit/filters/filter_form_builder_spec.rb | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/active_admin/inputs/filters/select_input.rb b/lib/active_admin/inputs/filters/select_input.rb index cdaccc2e436..d9187e29094 100644 --- a/lib/active_admin/inputs/filters/select_input.rb +++ b/lib/active_admin/inputs/filters/select_input.rb @@ -45,7 +45,8 @@ def collection end def pluck_column - klass.reorder("#{method} asc").uniq.pluck method + distinct = ActiveAdmin::Dependency.rails >= 4 ? :distinct : :uniq + klass.reorder("#{method} asc").public_send(distinct).pluck method end end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 5a7cafeb519..9c6c99db08b 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -143,8 +143,9 @@ def filter(name, options = {}) it "should remove original ordering to prevent PostgreSQL error" do expect(scope.object.klass).to receive(:reorder).with('title asc') { - m = double uniq: double(pluck: ['A Title']) - expect(m.uniq).to receive(:pluck).with :title + distinct = ActiveAdmin::Dependency.rails >= 4 ? :distinct : :uniq + m = double distinct => double(pluck: ['A Title']) + expect(m.send(distinct)).to receive(:pluck).with :title m } body From d617e00c54db1701625f28f85b57e215cd65e0a8 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 14:35:45 -0600 Subject: [PATCH 0062/3836] handle `redirect_to :back` API change --- lib/active_admin/base_controller.rb | 5 +++++ .../base_controller/authorization.rb | 7 +------ lib/active_admin/dependency.rb | 18 +++++++++++++++++- lib/active_admin/orm/active_record/comments.rb | 14 ++++++++++---- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/active_admin/base_controller.rb b/lib/active_admin/base_controller.rb index 2a8bc77300a..0cc82ac08bf 100644 --- a/lib/active_admin/base_controller.rb +++ b/lib/active_admin/base_controller.rb @@ -78,5 +78,10 @@ def determine_active_admin_layout ACTIVE_ADMIN_ACTIONS.include?(params[:action].to_sym) ? false : 'active_admin' end + def active_admin_root + controller, action = active_admin_namespace.root_to.split '#' + {controller: controller, action: action} + end + end end diff --git a/lib/active_admin/base_controller/authorization.rb b/lib/active_admin/base_controller/authorization.rb index 2e9c0ec4ddc..301b01ebebd 100644 --- a/lib/active_admin/base_controller/authorization.rb +++ b/lib/active_admin/base_controller/authorization.rb @@ -120,12 +120,7 @@ def rescue_active_admin_access_denied(exception) end def redirect_backwards_or_to_root - if request.headers.key? "HTTP_REFERER" - redirect_to :back - else - controller, action = active_admin_namespace.root_to.split '#' - redirect_to controller: controller, action: action - end + ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root end end diff --git a/lib/active_admin/dependency.rb b/lib/active_admin/dependency.rb index f3e3f17098f..3875b89bc3b 100644 --- a/lib/active_admin/dependency.rb +++ b/lib/active_admin/dependency.rb @@ -55,6 +55,10 @@ def self.[](name) Matcher.new name.to_s end + def self.rails5? + rails >= '5.beta' + end + class Matcher attr_reader :name @@ -131,12 +135,24 @@ def initialize(version) class Rails < Base def parameterize(string) - if @version >= '5.beta' + if Dependency.rails5? string.parameterize separator: '_' else string.parameterize '_' end end + + def redirect_back(controller, fallback_location:) + controller.instance_exec do + if Dependency.rails5? + redirect_back fallback_location: fallback_location + elsif controller.request.headers.key? 'HTTP_REFERER' + redirect_to :back + else + redirect_to fallback_location + end + end + end end end diff --git a/lib/active_admin/orm/active_record/comments.rb b/lib/active_admin/orm/active_record/comments.rb index 6378a9d2484..93f20328308 100644 --- a/lib/active_admin/orm/active_record/comments.rb +++ b/lib/active_admin/orm/active_record/comments.rb @@ -55,17 +55,23 @@ def scoped_collection # Redirect to the resource show page after comment creation def create create! do |success, failure| - success.html{ redirect_to :back } + success.html do + ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + end failure.html do flash[:error] = I18n.t 'active_admin.comments.errors.empty_text' - redirect_to :back + ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root end end def destroy destroy! do |success, failure| - success.html { redirect_to :back } - failure.html { redirect_to :back } + success.html do + ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + end + failure.html do + ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + end end end end From 494b0c64ea254c574eba7be1c15cb4f0e3cd1be2 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 15:22:48 -0600 Subject: [PATCH 0063/3836] more callback fixes --- docs/3-index-pages.md | 2 +- features/index/page_title.feature | 3 ++- features/show/page_title.feature | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index 698ecc8df22..e076a00d4ad 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -218,7 +218,7 @@ You can change it per request / action too: ```ruby controller do - before_filter :only => :index do + before_action only: :index do @per_page = 100 end end diff --git a/features/index/page_title.feature b/features/index/page_title.feature index 277f24a871c..7eca0e5db58 100644 --- a/features/index/page_title.feature +++ b/features/index/page_title.feature @@ -34,7 +34,8 @@ Feature: Index - Page Title """ ActiveAdmin.register Post do controller do - before_filter { @page_title = "List of #{resource_class.model_name.plural}" } + callback = ActiveAdmin::Dependency.rails >= 4 ? :before_action : :before_filter + send(callback) { @page_title = "List of #{resource_class.model_name.plural}" } end end """ diff --git a/features/show/page_title.feature b/features/show/page_title.feature index bc9bf56f6d1..0f1dad67b97 100644 --- a/features/show/page_title.feature +++ b/features/show/page_title.feature @@ -51,7 +51,8 @@ Feature: Show - Page Title """ ActiveAdmin.register Post do controller do - before_filter { @page_title = "List of #{resource_class.model_name.plural}" } + callback = ActiveAdmin::Dependency.rails >= 4 ? :before_action : :before_filter + send(callback) { @page_title = "List of #{resource_class.model_name.plural}" } end end """ From 4effc7be0f509752eadeb09118f977b05d53399a Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 15:27:28 -0600 Subject: [PATCH 0064/3836] call `to_unsafe_h` on filter params --- lib/active_admin/filters/active.rb | 7 ++++--- lib/active_admin/resource_controller/data_access.rb | 12 +++++------- lib/active_admin/view_helpers/fields_for.rb | 5 +++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/active_admin/filters/active.rb b/lib/active_admin/filters/active.rb index d01e7652962..c0d58dd8b3d 100644 --- a/lib/active_admin/filters/active.rb +++ b/lib/active_admin/filters/active.rb @@ -7,7 +7,8 @@ class Active attr_accessor :filters, :scope def initialize(resource_class, params) - @resource_class, @params = resource_class, params + @resource_class = resource_class + @params = params.respond_to?(:to_unsafe_h) ? params.to_unsafe_h : params @scope = humanize_scope @filters = build_filters end @@ -15,8 +16,8 @@ def initialize(resource_class, params) private def build_filters - @params[:q] ||= [] - @params[:q].map { |param| Humanized.new(param) } + filters = @params[:q] || [] + filters.map{ |param| Humanized.new(param) } end def humanize_scope diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index 352d06cc4d1..fc68fd09c7a 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -222,16 +222,14 @@ def apply_sorting(chain) # Applies any Ransack search methods to the currently scoped collection. # Both `search` and `ransack` are provided, but we use `ransack` to prevent conflicts. def apply_filtering(chain) - @search = chain.ransack clean_search_params params[:q] + @search = chain.ransack clean_search_params @search.result end - def clean_search_params(params) - if params.is_a? Hash - params.dup.delete_if{ |key, value| value.blank? } - else - {} - end + def clean_search_params + q = params[:q] || {} + q = q.to_unsafe_h if q.respond_to? :to_unsafe_h + q.delete_if{ |key, value| value.blank? } end def apply_scoping(chain) diff --git a/lib/active_admin/view_helpers/fields_for.rb b/lib/active_admin/view_helpers/fields_for.rb index a27128d0d70..87a3f08cdd8 100644 --- a/lib/active_admin/view_helpers/fields_for.rb +++ b/lib/active_admin/view_helpers/fields_for.rb @@ -15,11 +15,12 @@ module FormHelper # def fields_for_params(params, options = {}) namespace = options[:namespace] - except = options[:except].is_a?(Array) ? options[:except] : [options[:except]] + except = Array.wrap(options[:except]).map &:to_s + params = params.respond_to?(:to_unsafe_h) ? params.to_unsafe_h : params params.flat_map do |k, v| next if namespace.nil? && %w(controller action commit utf8).include?(k.to_s) - next if except.map(&:to_s).include?(k.to_s) + next if except.include?(k.to_s) if namespace k = "#{namespace}[#{k}]" From 05af646e52e8837beba8288aede846786d8c170d Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 15:39:04 -0600 Subject: [PATCH 0065/3836] don't call an enumerable method directly on a query object --- lib/active_admin/views/index_as_grid.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/views/index_as_grid.rb b/lib/active_admin/views/index_as_grid.rb index 2a90e1dbd7e..37bff683122 100644 --- a/lib/active_admin/views/index_as_grid.rb +++ b/lib/active_admin/views/index_as_grid.rb @@ -29,7 +29,7 @@ class IndexAsGrid < ActiveAdmin::Component def build(page_presenter, collection) @page_presenter = page_presenter - @collection = collection + @collection = collection.to_a add_class "index" build_table end @@ -47,7 +47,7 @@ def self.index_name def build_table resource_selection_toggle_panel if active_admin_config.batch_actions.any? table class: "index_grid" do - collection.in_groups_of(number_of_columns).each do |group| + @collection.in_groups_of(number_of_columns).each do |group| build_row(group) end end From 4f2916bef684c695afd6346e2365e4d0bdc25927 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 15:40:04 -0600 Subject: [PATCH 0066/3836] url_for with minimal args will just be a link to the same page this code was causing a security warning from Rails --- lib/active_admin/views/components/index_list.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/views/components/index_list.rb b/lib/active_admin/views/components/index_list.rb index 97013b437a0..90a39042465 100644 --- a/lib/active_admin/views/components/index_list.rb +++ b/lib/active_admin/views/components/index_list.rb @@ -36,7 +36,7 @@ def build(index_classes) # @param [Class] index_class The class on which to build the link and html classes def build_index_list(index_class) li class: classes_for_index(index_class) do - a href: url_for(params.merge(as: index_class.index_name.to_sym)), class: "table_tools_button" do + a href: url_for(as: index_class.index_name.to_sym), class: "table_tools_button" do name = index_class.index_name I18n.t("active_admin.index_list.#{name}", default: name.to_s.titleize) end From 4292aafa33910b705c3076f36e0cb8b2322dbca9 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 15:45:56 -0600 Subject: [PATCH 0067/3836] fix batch actions URL generation --- lib/active_admin/batch_actions/resource_extension.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/batch_actions/resource_extension.rb b/lib/active_admin/batch_actions/resource_extension.rb index fa89f914e55..4f3bf3607e7 100644 --- a/lib/active_admin/batch_actions/resource_extension.rb +++ b/lib/active_admin/batch_actions/resource_extension.rb @@ -54,8 +54,9 @@ def clear_batch_actions! # Path to the batch action itself def batch_action_path(params = {}) path = [route_collection_path(params), "batch_action"].join("/") - query = params.slice(:q, :scope).to_param - [path, query].reject(&:blank?).join("?") + query = params.slice(:q, :scope) + query = query.permit!.to_h if query.respond_to? :permit! + [path, query.to_param].reject(&:blank?).join("?") end private From 27aa617f50a93aebc363a289dc960257a714f272 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 15:55:43 -0600 Subject: [PATCH 0068/3836] fix CSV export content type header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for some unknown reason, Rails 5 sets to to text/html 💩 --- lib/active_admin/resource_controller/streaming.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/active_admin/resource_controller/streaming.rb b/lib/active_admin/resource_controller/streaming.rb index bcfc9150308..05d33d86fee 100644 --- a/lib/active_admin/resource_controller/streaming.rb +++ b/lib/active_admin/resource_controller/streaming.rb @@ -33,6 +33,7 @@ def csv_filename end def stream_csv + headers['Content-Type'] = 'text/csv; charset=utf-8' # In Rails 5 it's set to HTML?? headers['Content-Disposition'] = %{attachment; filename="#{csv_filename}"} stream_resource &active_admin_config.csv_builder.method(:build).to_proc.curry[self] end From 87770b456b9c73ac00712f0383fff803d97406d2 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 16:07:52 -0600 Subject: [PATCH 0069/3836] Rails 5 no longer provides a named route for namespaced root routes --- lib/active_admin/router.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/router.rb b/lib/active_admin/router.rb index f000b2fd99e..13c23d7b9be 100644 --- a/lib/active_admin/router.rb +++ b/lib/active_admin/router.rb @@ -24,7 +24,7 @@ def define_root_routes(router) root namespace.root_to_options.merge(to: namespace.root_to) else namespace namespace.name do - root namespace.root_to_options.merge(to: namespace.root_to) + root namespace.root_to_options.merge(to: namespace.root_to, as: :root) end end end From ee8287f0f8e35fab7f4a318e2a75c21b58378d36 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 16:21:31 -0600 Subject: [PATCH 0070/3836] turn on colored output for RSpec --- spec/rails_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 297133c800b..7ea42b8946d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -133,6 +133,7 @@ def with_translation(translation) config.filter_run focus: true config.filter_run_excluding skip: true config.run_all_when_everything_filtered = true + config.color = true end # All RSpec configuration needs to happen before any examples From d0e1f0a23776e4d507c7b654d2d997924e02b679 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 16:07:59 -0600 Subject: [PATCH 0071/3836] =?UTF-8?q?expect=20tests=20to=20pass=20for=20Ra?= =?UTF-8?q?ils=205=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 346d9cbd3d1..c236c034501 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,8 +27,6 @@ matrix: exclude: - rvm: 1.9 env: RAILS=master - allow_failures: - - env: RAILS=master branches: only: - master From 8dc76a17f9a19bcb824b9d19f27e02730002a591 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 17:07:17 -0600 Subject: [PATCH 0072/3836] =?UTF-8?q?we=20still=20have=20to=20support=20Ru?= =?UTF-8?q?by=201.9=20=F0=9F=92=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/active_admin/base_controller/authorization.rb | 2 +- lib/active_admin/dependency.rb | 2 +- lib/active_admin/orm/active_record/comments.rb | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/active_admin/base_controller/authorization.rb b/lib/active_admin/base_controller/authorization.rb index 301b01ebebd..15203f34b53 100644 --- a/lib/active_admin/base_controller/authorization.rb +++ b/lib/active_admin/base_controller/authorization.rb @@ -120,7 +120,7 @@ def rescue_active_admin_access_denied(exception) end def redirect_backwards_or_to_root - ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + ActiveAdmin::Dependency.rails.redirect_back self, active_admin_root end end diff --git a/lib/active_admin/dependency.rb b/lib/active_admin/dependency.rb index 3875b89bc3b..1e98cefcf10 100644 --- a/lib/active_admin/dependency.rb +++ b/lib/active_admin/dependency.rb @@ -142,7 +142,7 @@ def parameterize(string) end end - def redirect_back(controller, fallback_location:) + def redirect_back(controller, fallback_location) controller.instance_exec do if Dependency.rails5? redirect_back fallback_location: fallback_location diff --git a/lib/active_admin/orm/active_record/comments.rb b/lib/active_admin/orm/active_record/comments.rb index 93f20328308..921eab1c5e8 100644 --- a/lib/active_admin/orm/active_record/comments.rb +++ b/lib/active_admin/orm/active_record/comments.rb @@ -56,21 +56,21 @@ def scoped_collection def create create! do |success, failure| success.html do - ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + ActiveAdmin::Dependency.rails.redirect_back self, active_admin_root end failure.html do flash[:error] = I18n.t 'active_admin.comments.errors.empty_text' - ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + ActiveAdmin::Dependency.rails.redirect_back self, active_admin_root end end def destroy destroy! do |success, failure| success.html do - ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + ActiveAdmin::Dependency.rails.redirect_back self, active_admin_root end failure.html do - ActiveAdmin::Dependency.rails.redirect_back self, fallback_location: active_admin_root + ActiveAdmin::Dependency.rails.redirect_back self, active_admin_root end end end From 6306114992a5a9bd1b24740014d7b869454558f1 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 17:08:32 -0600 Subject: [PATCH 0073/3836] fix version check --- spec/unit/action_builder_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb index ddd38f1be37..8c29de44ad1 100644 --- a/spec/unit/action_builder_spec.rb +++ b/spec/unit/action_builder_spec.rb @@ -63,7 +63,7 @@ it 'sets the page title' do params = {id: 1} - params = {params: params} if ActiveAdmin::Dependency.rails > 4 + params = {params: params} if ActiveAdmin::Dependency.rails5? get :comment, params expect(controller.instance_variable_get(:@page_title)).to eq 'My Awesome Comment' From 78c17f67909f2ee8a2ef26e59b13d50134a6b207 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 19:55:57 -0600 Subject: [PATCH 0074/3836] skip the sidebar spec on Rails 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original implementation of this test still passes, but for some reason Rails 3.2 doesn’t actually run any callbacks defined in this test. As old as Rails 3.2 is, I think it’s fine to skip. We’re going to be dropping support for it soon anyways. --- spec/unit/resource_controller/sidebars_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index 41ac52cf822..28bed17cb02 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -35,4 +35,4 @@ expect(controller.instance_variable_get(:@skip_sidebar)).to eq true end end -end +end unless ActiveAdmin::Dependency.rails < 4 From 7c4128ed5105e8d354e94940e9c0fd7cd7846132 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 19:57:40 -0600 Subject: [PATCH 0075/3836] still call `render text:` on Rails < 5 --- lib/active_admin/base_controller/authorization.rb | 4 +++- spec/unit/authorization/index_overriding_spec.rb | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/base_controller/authorization.rb b/lib/active_admin/base_controller/authorization.rb index 15203f34b53..e7ed7f54e61 100644 --- a/lib/active_admin/base_controller/authorization.rb +++ b/lib/active_admin/base_controller/authorization.rb @@ -113,7 +113,9 @@ def rescue_active_admin_access_denied(exception) redirect_backwards_or_to_root end - format.csv { render body: error, status: :unauthorized } + body = ActiveAdmin::Dependency.rails5? ? :body : :text + + format.csv { render body => error, status: :unauthorized } format.json { render json: { error: error }, status: :unauthorized } format.xml { render xml: "#{error}", status: :unauthorized } end diff --git a/spec/unit/authorization/index_overriding_spec.rb b/spec/unit/authorization/index_overriding_spec.rb index f1baf6b50af..dc718b35d3b 100644 --- a/spec/unit/authorization/index_overriding_spec.rb +++ b/spec/unit/authorization/index_overriding_spec.rb @@ -5,7 +5,8 @@ controller.instance_eval do def index super do - render body: 'Rendered from passed block' and return + body = ActiveAdmin::Dependency.rails5? ? :body : :text + render body => 'Rendered from passed block' and return end end end From f6061bec47068f8955c9c978bd561c817f12651c Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 21:29:26 -0600 Subject: [PATCH 0076/3836] Stop testing against Rails 4.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We’re getting this error: ``` undefined method `to_h' for {}:ActionController::Parameters ``` The odd thing is Rails 4.1 on Ruby 2 and JRuby are passing just fine. It’s only Rails 4.1 on Ruby 1.9 that’s failing. I don’t think it’s important to run the test suite on Rails 4.1, and we’ll be dropping support for it soon anyway, so this commit removes it from Travis. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c236c034501..8b118e9aa92 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,6 @@ rvm: env: matrix: - RAILS=3.2.22 - - RAILS=4.1.14 - RAILS=4.2.5 - RAILS=master global: From 8dbd357f403dd70f327b0a57d7c48e0a9f64bcfe Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 21:32:28 -0600 Subject: [PATCH 0077/3836] try getting Rails 5 running on JRuby https://github.com/jruby/activerecord-jdbc-adapter/issues/700 --- Gemfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 0cf57ebd114..67533357c33 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,7 @@ if rails_version == 'master' end gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' gem 'database_cleaner', github: 'pschambacher/database_cleaner', branch: 'rails5.0', ref: '8dd9fa4' + gem 'activerecord-jdbc-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: :jruby end # Optional dependencies @@ -78,6 +79,6 @@ group :test do gem 'i18n-spec' gem 'shoulda-matchers', '<= 2.8.0' gem 'sqlite3', platforms: :mri - gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby + gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby if rails_version != 'master' gem 'poltergeist' end From 16aba00450ac5689bd3e5548ee39ccd259cbd32c Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 7 Feb 2016 22:07:57 -0600 Subject: [PATCH 0078/3836] allow JRuby to fail on Rails 5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the previous commit tried using the ActiveRecord adapter gem from Github / master as mentioned here: https://github.com/jruby/activerecord-jdbc-adapter/issues/700, but that didn’t seem to have worked --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8b118e9aa92..04a1ddb7c25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,9 @@ matrix: exclude: - rvm: 1.9 env: RAILS=master + allow_failures: + - rvm: jruby-9.0.4.0 + env: RAILS=master branches: only: - master From 4349a2237894aae45569c5a7d25488081ba2d32f Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Tue, 9 Feb 2016 09:28:06 +0100 Subject: [PATCH 0079/3836] Update de.yml --- config/locales/de.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/de.yml b/config/locales/de.yml index b29ec2315a3..3ac9eeb5b24 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -32,6 +32,7 @@ de: greater_than: "Größer als" less_than: "Kleiner als" search_status: + headline: "Filter" current_scope: "Anwendungsbereich:" current_filters: "Aktuelle Filter:" no_current_filters: "Keine" From 68855f4a8bbed7a30427619f5ff5205c6da792d2 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 13:48:04 -0600 Subject: [PATCH 0080/3836] use Rubygems versions where available I copied the `> 5.x` version requirement from https://github.com/rails/activemodel-serializers-xml/commit/b8173f0cdb9da9916755e25ddd5f034ecb04b55f --- .travis.yml | 8 ++++---- Gemfile | 29 ++++++++--------------------- features/support/env.rb | 2 +- lib/active_admin/dependency.rb | 2 +- script/local | 2 +- tasks/test.rake | 2 +- 6 files changed, 16 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index 04a1ddb7c25..a7eed4464f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,20 +18,20 @@ env: matrix: - RAILS=3.2.22 - RAILS=4.2.5 - - RAILS=master + - RAILS=> 5.x global: - JRUBY_OPTS="-J-Xmx1024m --debug" matrix: fast_finish: true exclude: - rvm: 1.9 - env: RAILS=master + env: RAILS=> 5.x allow_failures: - rvm: jruby-9.0.4.0 - env: RAILS=master + env: RAILS=> 5.x branches: only: - - master + - "> 5.x" - /\A\d-\d-stable\z/ notifications: irc: diff --git a/Gemfile b/Gemfile index 67533357c33..e930fe6d574 100644 --- a/Gemfile +++ b/Gemfile @@ -5,26 +5,18 @@ gemspec require File.expand_path 'spec/support/detect_rails_version', File.dirname(__FILE__) rails_version = detect_rails_version -gem 'rails', rails_version == 'master' ? {github: 'rails/rails'} : rails_version +gem 'rails', rails_version gem 'jquery-ui-rails', rails_version[0] == '3' ? '~> 4.0' : '~> 5.0' gem 'test-unit', '~> 3.0' if rails_version[0] == '3' -if rails_version == 'master' - gem 'arel', github: 'rails/arel' - # gem 'sprockets', github: 'rails/sprockets' - # gem 'sass-rails', github: 'rails/sass-rails' - gem 'rack', github: 'rack/rack' - gem 'devise', github: 'plataformatec/devise' +if rails_version == '> 5.x' gem 'ransack', github: 'activerecord-hackery/ransack' gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable' gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587' gem 'formtastic', github: 'justinfrench/formtastic' gem 'activemodel-serializers-xml', github: 'rails/activemodel-serializers-xml' # drapergem/draper#697 - %w[rspec-core rspec-expectations rspec-mocks rspec-rails rspec-support].each do |lib| - gem lib, github: "rspec/#{lib}" - end gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' gem 'database_cleaner', github: 'pschambacher/database_cleaner', branch: 'rails5.0', ref: '8dd9fa4' gem 'activerecord-jdbc-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: :jruby @@ -32,10 +24,8 @@ end # Optional dependencies gem 'cancan' -if rails_version != 'master' - gem 'devise' - gem 'draper' -end +gem 'devise', rails_version == '> 5.x' ? '> 4.x' : '~> 3.5' +gem 'draper' if rails_version != '> 5.x' gem 'pundit' # Utility gems used in both development & test environments @@ -51,7 +41,7 @@ group :development do gem 'binding_of_caller', platforms: :mri # Retrieve the binding of a method's caller in MRI Ruby >= 1.9.2 # Performance - gem 'rack-mini-profiler' if rails_version != 'master' # Inline app profiler. See ?pp=help for options. + gem 'rack-mini-profiler' if rails_version != '> 5.x' # Inline app profiler. See ?pp=help for options. gem 'flamegraph', platforms: :mri # Flamegraph visualiztion: ?pp=flamegraph # Documentation @@ -66,19 +56,16 @@ group :test do gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' - gem 'database_cleaner' if rails_version != 'master' + gem 'database_cleaner' if rails_version != '> 5.x' gem 'guard-rspec', require: false gem 'jasmine' gem 'jslint_on_rails' gem 'launchy' gem 'rails-i18n' # Provides default i18n for many languages - if rails_version != 'master' - gem 'rspec' - gem 'rspec-rails' - end + gem 'rspec-rails', '>= 3.5.0.beta1' gem 'i18n-spec' gem 'shoulda-matchers', '<= 2.8.0' gem 'sqlite3', platforms: :mri - gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby if rails_version != 'master' + gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby if rails_version != '> 5.x' gem 'poltergeist' end diff --git a/features/support/env.rb b/features/support/env.rb index b31dcb39fb7..fefcd2691ed 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -130,7 +130,7 @@ ActiveSupport::Deprecation.behavior = -> message, callstack do e = StandardError.new message e.set_backtrace callstack.map(&:to_s) - puts e + puts e # sometimes Cucumber otherwise won't show the error message raise e end diff --git a/lib/active_admin/dependency.rb b/lib/active_admin/dependency.rb index 1e98cefcf10..e09e3339246 100644 --- a/lib/active_admin/dependency.rb +++ b/lib/active_admin/dependency.rb @@ -56,7 +56,7 @@ def self.[](name) end def self.rails5? - rails >= '5.beta' + rails >= '5.x' end class Matcher diff --git a/script/local b/script/local index ce22c161009..8ecda7cd103 100755 --- a/script/local +++ b/script/local @@ -22,7 +22,7 @@ end rails_version = detect_rails_version! test_app_dir = ".test-rails-apps" -test_app_path = "#{test_app_dir}/test-rails-app-#{rails_version}" +test_app_path = "#{test_app_dir}/test-rails-app-#{Shellwords.escape rails_version}" # Ensure .test-rails-apps is created system "mkdir #{test_app_dir}" unless File.exists?(test_app_dir) diff --git a/tasks/test.rake b/tasks/test.rake index b8aa81fe170..1d711ae91b8 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,7 +1,7 @@ desc "Creates a test rails app for the specs to run against" task :setup, :parallel do |t, opts| require 'rails/version' - if File.exists? dir = "spec/rails/rails-#{detect_rails_version}" + if File.exists? dir = "spec/rails/rails-#{Shellwords.escape detect_rails_version}" puts "test app #{dir} already exists; skipping" else system 'mkdir -p spec/rails' From a83dd28837788b17002e43f80a17da94b318dcdd Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 13:52:49 -0600 Subject: [PATCH 0081/3836] test against Ruby 2.3 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a7eed4464f1..c2c5ce4e3b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ script: - bundle exec rake test_with_coveralls rvm: - 1.9 - - 2.2.3 + - 2.3 - jruby-9.0.4.0 env: matrix: From ca5a8b80c4a5d43a58cb9d7a3ee8554b55ca0d50 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 14:23:18 -0600 Subject: [PATCH 0082/3836] move strong_parameters conditions into Dependency class --- lib/active_admin/dependency.rb | 4 ++++ lib/active_admin/orm/active_record/comments.rb | 3 +-- lib/generators/active_admin/resource/templates/admin.rb | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/active_admin/dependency.rb b/lib/active_admin/dependency.rb index e09e3339246..89a967eb9eb 100644 --- a/lib/active_admin/dependency.rb +++ b/lib/active_admin/dependency.rb @@ -134,6 +134,10 @@ def initialize(version) end class Rails < Base + def strong_parameters? + @version >= 4 || defined?(ActionController::StrongParameters) + end + def parameterize(string) if Dependency.rails5? string.parameterize separator: '_' diff --git a/lib/active_admin/orm/active_record/comments.rb b/lib/active_admin/orm/active_record/comments.rb index 921eab1c5e8..9d7e7db4c5c 100644 --- a/lib/active_admin/orm/active_record/comments.rb +++ b/lib/active_admin/orm/active_record/comments.rb @@ -77,8 +77,7 @@ def destroy end end - # Set up permitted params in case the app is using Strong Parameters - unless Rails::VERSION::MAJOR == 3 && !defined? StrongParameters + if ActiveAdmin::Dependency.rails.strong_parameters? permit_params :body, :namespace, :resource_id, :resource_type end diff --git a/lib/generators/active_admin/resource/templates/admin.rb b/lib/generators/active_admin/resource/templates/admin.rb index 9bc592df8fa..c4105241760 100644 --- a/lib/generators/active_admin/resource/templates/admin.rb +++ b/lib/generators/active_admin/resource/templates/admin.rb @@ -1,5 +1,5 @@ ActiveAdmin.register <%= class_name %> do -<% if Rails::VERSION::MAJOR >= 4 || defined?(ActionController::StrongParameters) %> +<% if ActiveAdmin::Dependency.rails.strong_parameters? %> # See permitted parameters documentation: # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters # From c740f4ac81a8486961326af98a366768fa8c92e6 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 14:23:45 -0600 Subject: [PATCH 0083/3836] move render key into Dependency class --- lib/active_admin/base_controller/authorization.rb | 2 +- lib/active_admin/dependency.rb | 4 ++++ spec/unit/authorization/index_overriding_spec.rb | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/active_admin/base_controller/authorization.rb b/lib/active_admin/base_controller/authorization.rb index e7ed7f54e61..4a2b748a100 100644 --- a/lib/active_admin/base_controller/authorization.rb +++ b/lib/active_admin/base_controller/authorization.rb @@ -113,7 +113,7 @@ def rescue_active_admin_access_denied(exception) redirect_backwards_or_to_root end - body = ActiveAdmin::Dependency.rails5? ? :body : :text + body = ActiveAdmin::Dependency.rails.render_key format.csv { render body => error, status: :unauthorized } format.json { render json: { error: error }, status: :unauthorized } diff --git a/lib/active_admin/dependency.rb b/lib/active_admin/dependency.rb index 89a967eb9eb..7cf21ad8e18 100644 --- a/lib/active_admin/dependency.rb +++ b/lib/active_admin/dependency.rb @@ -157,6 +157,10 @@ def redirect_back(controller, fallback_location) end end end + + def render_key + Dependency.rails5? ? :body : :text + end end end diff --git a/spec/unit/authorization/index_overriding_spec.rb b/spec/unit/authorization/index_overriding_spec.rb index dc718b35d3b..40377284007 100644 --- a/spec/unit/authorization/index_overriding_spec.rb +++ b/spec/unit/authorization/index_overriding_spec.rb @@ -5,8 +5,8 @@ controller.instance_eval do def index super do - body = ActiveAdmin::Dependency.rails5? ? :body : :text - render body => 'Rendered from passed block' and return + render Dependency.rails.render_key => 'Rendered from passed block' + return end end end From e2ba34004cb6fc8640455233557734ea3a642290 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 16:27:22 -0600 Subject: [PATCH 0084/3836] try fixing Travis also the final line was an unintentional change --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c2c5ce4e3b4..7c96a6669b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,20 +18,20 @@ env: matrix: - RAILS=3.2.22 - RAILS=4.2.5 - - RAILS=> 5.x + - RAILS="> 5.x" global: - JRUBY_OPTS="-J-Xmx1024m --debug" matrix: fast_finish: true exclude: - rvm: 1.9 - env: RAILS=> 5.x + env: RAILS="> 5.x" allow_failures: - rvm: jruby-9.0.4.0 - env: RAILS=> 5.x + env: RAILS="> 5.x" branches: only: - - "> 5.x" + - master - /\A\d-\d-stable\z/ notifications: irc: From f4e0629313bc728206485a159bb582bc7b9a233c Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 16:31:37 -0600 Subject: [PATCH 0085/3836] "2.3" isn't recognized by RVM / Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7c96a6669b4..6745e0783b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ script: - bundle exec rake test_with_coveralls rvm: - 1.9 - - 2.3 + - 2.3.0 - jruby-9.0.4.0 env: matrix: From 5c5080953414cda8cd3664e94f80e7ab1bfd6785 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 17:20:16 -0600 Subject: [PATCH 0086/3836] add documentation to the README --- Gemfile | 1 + README.md | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index e930fe6d574..1dc46b0d23a 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ gem 'jquery-ui-rails', rails_version[0] == '3' ? '~> 4.0' : '~> 5.0' gem 'test-unit', '~> 3.0' if rails_version[0] == '3' if rails_version == '> 5.x' + # Note: when updating this list, be sure to also update the README gem 'ransack', github: 'activerecord-hackery/ransack' gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable' gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587' diff --git a/README.md b/README.md index 78d820bac44..39f908d95db 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Active Admin is a Ruby on Rails framework for creating elegant backends for webs ### 1.0.0 We're [currently working on 1.0.0](https://github.com/activeadmin/activeadmin/issues?milestone=18), -which as far as dependencies, moves us from meta_search to Ransack and adds Rails 4 support. +which as far as dependencies, moves us from meta_search to Ransack and adds Rails 4 & 5 support. You can get it by tracking master: ```ruby @@ -27,6 +27,28 @@ gem 'activeadmin', '~> 1.0.0.pre2' *Keep in mind that during the time where we use `pre`-release label, things can break in each release!* +### Rails 5 + +Active Admin master has preliminary support for Rails 5. To give it a try, these Gemfile changes may be needed: + +```ruby +gem 'devise', '> 4.x' +gem 'rspec-rails', '>= 3.5.0.beta1' +gem 'ransack', github: 'activerecord-hackery/ransack' +gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable' +gem 'formtastic', github: 'justinfrench/formtastic' +gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587' +# To fix a Draper deprecation error +gem 'activemodel-serializers-xml', github: 'rails/activemodel-serializers-xml' +# Optional -- only if you already include these gems +gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' +gem 'database_cleaner', github: 'pschambacher/database_cleaner', branch: 'rails5.0', ref: '8dd9fa4' +# Only for JRuby: +gem 'activerecord-jdbc-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: :jruby +``` + +If something isn't working for you please report it on [#4177](https://github.com/activeadmin/activeadmin/issues/4177). + ### 0.6.x The plan is to follow [semantic versioning](http://semver.org/) as of 1.0.0. The 0.6.x line will From 69aa5b5db73b3efefd6fea2f07865d9d162ac6de Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 20:31:42 -0600 Subject: [PATCH 0087/3836] `be_nil` -> `eq nil` --- features/step_definitions/attribute_steps.rb | 4 ++-- features/step_definitions/filter_steps.rb | 2 +- features/step_definitions/format_steps.rb | 2 +- spec/requests/stylesheets_spec.rb | 2 +- spec/unit/batch_actions/resource_spec.rb | 2 +- spec/unit/comments_spec.rb | 2 +- spec/unit/menu_collection_spec.rb | 6 +++--- spec/unit/namespace/register_page_spec.rb | 8 ++++---- spec/unit/namespace/register_resource_spec.rb | 12 ++++++------ spec/unit/namespace_spec.rb | 8 ++++---- spec/unit/resource/action_items_spec.rb | 2 +- spec/unit/resource/routes_spec.rb | 2 +- spec/unit/resource/scopes_spec.rb | 4 ++-- spec/unit/resource_spec.rb | 6 +++--- spec/unit/scope_spec.rb | 4 ++-- spec/unit/views/components/attributes_table_spec.rb | 2 +- 16 files changed, 34 insertions(+), 34 deletions(-) diff --git a/features/step_definitions/attribute_steps.rb b/features/step_definitions/attribute_steps.rb index 84dad126b10..a865b08f51c 100644 --- a/features/step_definitions/attribute_steps.rb +++ b/features/step_definitions/attribute_steps.rb @@ -1,6 +1,6 @@ Then /^I should see the attribute "([^"]*)" with "([^"]*)"$/ do |title, value| elems = all ".attributes_table th:contains('#{title}') ~ td:contains('#{value}')" - expect(elems.first).to_not be_nil, 'attribute missing' + expect(elems.first).to_not eq(nil), 'attribute missing' end Then /^I should see the attribute "([^"]*)" with a nicely formatted datetime$/ do |title| @@ -10,7 +10,7 @@ Then /^the attribute "([^"]*)" should be empty$/ do |title| elems = all ".attributes_table th:contains('#{title}') ~ td > span.empty" - expect(elems.first).to_not be_nil, 'attribute not empty' + expect(elems.first).to_not eq(nil), 'attribute not empty' end Then /^I should not see the attribute "([^"]*)"$/ do |title| diff --git a/features/step_definitions/filter_steps.rb b/features/step_definitions/filter_steps.rb index 02e91f20008..71e2961c2b4 100644 --- a/features/step_definitions/filter_steps.rb +++ b/features/step_definitions/filter_steps.rb @@ -32,7 +32,7 @@ expect(params[key]).to_not eq value if negative expect(params[key]).to eq value unless negative else - expect(params[key]).to be_nil if negative + expect(params[key]).to eq nil if negative expect(params[key]).to be_present unless negative end end diff --git a/features/step_definitions/format_steps.rb b/features/step_definitions/format_steps.rb index 15810260f80..65327d6b177 100644 --- a/features/step_definitions/format_steps.rb +++ b/features/step_definitions/format_steps.rb @@ -24,7 +24,7 @@ expected_row.each_with_index do |expected_cell, col_index| cell = csv.try(:[], row_index).try(:[], col_index) if expected_cell.blank? - expect(cell).to be_nil + expect(cell).to eq nil else expect(cell || '').to match /#{expected_cell}/ end diff --git a/spec/requests/stylesheets_spec.rb b/spec/requests/stylesheets_spec.rb index 52437a61343..00d0f5ff3bf 100644 --- a/spec/requests/stylesheets_spec.rb +++ b/spec/requests/stylesheets_spec.rb @@ -9,7 +9,7 @@ assets.find_asset("active_admin.css") end it "should successfully render the scss stylesheets using sprockets" do - expect(css).to_not be_nil + expect(css).to_not eq nil end it "should not have any syntax errors" do expect(css.to_s).to_not include("Syntax error:") diff --git a/spec/unit/batch_actions/resource_spec.rb b/spec/unit/batch_actions/resource_spec.rb index bff65d12ac1..cae06ceee54 100644 --- a/spec/unit/batch_actions/resource_spec.rb +++ b/spec/unit/batch_actions/resource_spec.rb @@ -35,7 +35,7 @@ end it "should store the block in the batch action" do - expect(resource.batch_actions.first.block).to_not be_nil + expect(resource.batch_actions.first.block).to_not eq nil end end diff --git a/spec/unit/comments_spec.rb b/spec/unit/comments_spec.rb index 25fd4f8569d..d066fc16c86 100644 --- a/spec/unit/comments_spec.rb +++ b/spec/unit/comments_spec.rb @@ -174,7 +174,7 @@ it "should add an attr_accessor :comments to ActiveAdmin::Resource" do ns = ActiveAdmin::Namespace.new(application, :admin) resource = ActiveAdmin::Resource.new(ns, Post) - expect(resource.comments).to be_nil + expect(resource.comments).to eq nil resource.comments = true expect(resource.comments).to be_truthy end diff --git a/spec/unit/menu_collection_spec.rb b/spec/unit/menu_collection_spec.rb index 9616c4d8f7f..b01f4b95635 100644 --- a/spec/unit/menu_collection_spec.rb +++ b/spec/unit/menu_collection_spec.rb @@ -44,7 +44,7 @@ m.add :default, label: "Hello World" end - expect(menus.fetch(:default)["Hello World"]).to_not be_nil + expect(menus.fetch(:default)["Hello World"]).to_not eq nil end it "re-runs the callbacks when the menu is cleared" do @@ -52,9 +52,9 @@ m.add :default, label: "Hello World" end - expect(menus.fetch(:default)["Hello World"]).to_not be_nil + expect(menus.fetch(:default)["Hello World"]).to_not eq nil menus.clear! - expect(menus.fetch(:default)["Hello World"]).to_not be_nil + expect(menus.fetch(:default)["Hello World"]).to_not eq nil end end diff --git a/spec/unit/namespace/register_page_spec.rb b/spec/unit/namespace/register_page_spec.rb index 1db8c1213ce..81ef7abff93 100644 --- a/spec/unit/namespace/register_page_spec.rb +++ b/spec/unit/namespace/register_page_spec.rb @@ -38,7 +38,7 @@ end it "should add a new menu item" do - expect(menu['Status']).to_not be_nil + expect(menu['Status']).to_not eq nil end end @@ -50,11 +50,11 @@ end it "should generate the parent menu item" do - expect( menu['Extra']).to_not be_nil + expect( menu['Extra']).to_not eq nil end it "should generate its own child item" do - expect(menu['Extra']['Status']).to_not be_nil + expect(menu['Extra']['Status']).to_not eq nil end end @@ -66,7 +66,7 @@ end it "should not create a menu item" do - expect(menu["Status"]).to be_nil + expect(menu["Status"]).to eq nil end end end diff --git a/spec/unit/namespace/register_resource_spec.rb b/spec/unit/namespace/register_resource_spec.rb index 63aec588c4c..17d232b29f8 100644 --- a/spec/unit/namespace/register_resource_spec.rb +++ b/spec/unit/namespace/register_resource_spec.rb @@ -88,7 +88,7 @@ module ::Mock; class Resource; def self.has_many(arg1, arg2); end; end; end namespace.register Category end it "should add a new menu item" do - expect(menu['Categories']).to_not be_nil + expect(menu['Categories']).to_not eq nil end end # describe "adding as a top level item" @@ -99,10 +99,10 @@ module ::Mock; class Resource; def self.has_many(arg1, arg2); end; end; end end end it "should generate the parent menu item" do - expect(menu['Blog']).to_not be_nil + expect(menu['Blog']).to_not eq nil end it "should generate its own child item" do - expect(menu['Blog']['Categories']).to_not be_nil + expect(menu['Blog']['Categories']).to_not eq nil end end # describe "adding as a child" @@ -113,7 +113,7 @@ module ::Mock; class Resource; def self.has_many(arg1, arg2); end; end; end end end it "should not create a menu item" do - expect(menu["Categories"]).to be_nil + expect(menu["Categories"]).to eq nil end end # describe "disabling the menu" @@ -125,7 +125,7 @@ module ::Mock; class Resource; def self.has_many(arg1, arg2); end; end; end end end it "should not show up in the menu" do - expect(menu["Posts"]).to be_nil + expect(menu["Posts"]).to eq nil end end context "when optional" do @@ -135,7 +135,7 @@ module ::Mock; class Resource; def self.has_many(arg1, arg2); end; end; end end end it "should show up in the menu" do - expect(menu["Posts"]).to_not be_nil + expect(menu["Posts"]).to_not eq nil end end end diff --git a/spec/unit/namespace_spec.rb b/spec/unit/namespace_spec.rb index 1f9a1becf46..75928625186 100644 --- a/spec/unit/namespace_spec.rb +++ b/spec/unit/namespace_spec.rb @@ -66,7 +66,7 @@ menu.add label: "menu item" end - expect(namespace.fetch_menu(:default)["menu item"]).to_not be_nil + expect(namespace.fetch_menu(:default)["menu item"]).to_not eq nil end it "should set a block on a custom menu" do @@ -74,7 +74,7 @@ menu.add label: "menu item" end - expect(namespace.fetch_menu(:test)["menu item"]).to_not be_nil + expect(namespace.fetch_menu(:test)["menu item"]).to_not eq nil end end @@ -89,12 +89,12 @@ end it "should have a logout button to the far left" do - expect(menu["Logout"]).to_not be_nil + expect(menu["Logout"]).to_not eq nil expect(menu["Logout"].priority).to eq 1 end it "should have a static link with a target of :blank" do - expect(menu["ActiveAdmin.info"]).to_not be_nil + expect(menu["ActiveAdmin.info"]).to_not eq nil expect(menu["ActiveAdmin.info"].html_options).to include(target: :blank) end diff --git a/spec/unit/resource/action_items_spec.rb b/spec/unit/resource/action_items_spec.rb index 4974ae0bf13..53d7a149d91 100644 --- a/spec/unit/resource/action_items_spec.rb +++ b/spec/unit/resource/action_items_spec.rb @@ -25,7 +25,7 @@ end it "should store the block in the action item" do - expect(resource.action_items.first.block).to_not be_nil + expect(resource.action_items.first.block).to_not eq nil end end diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index c79e948b943..478ab764a5b 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -25,7 +25,7 @@ module ActiveAdmin context "when in the root namespace" do let!(:config) { ActiveAdmin.register Category, namespace: false } it "should have a nil route_prefix" do - expect(config.route_prefix).to be_nil + expect(config.route_prefix).to eq nil end it "should generate a correct route" do diff --git a/spec/unit/resource/scopes_spec.rb b/spec/unit/resource/scopes_spec.rb index 3e132699f48..1a02f855bac 100644 --- a/spec/unit/resource/scopes_spec.rb +++ b/spec/unit/resource/scopes_spec.rb @@ -40,9 +40,9 @@ def config(options = {}) it "should update a scope with the same id" do config.scope :published - expect(config.scopes.first.scope_block).to be_nil + expect(config.scopes.first.scope_block).to eq nil config.scope(:published){ } - expect(config.scopes.first.scope_block).to_not be_nil + expect(config.scopes.first.scope_block).to_not eq nil end end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index ad699e5e119..327f7a0c290 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -35,7 +35,7 @@ def config(options = {}) describe '#decorator_class' do it 'returns nil by default' do - expect(config.decorator_class).to be_nil + expect(config.decorator_class).to eq nil end context 'when a decorator is defined' do let(:resource) { namespace.register(Post) { decorate_with PostDecorator } } @@ -80,9 +80,9 @@ def config(options = {}) describe "#belongs_to" do it "should build a belongs to configuration" do - expect(config.belongs_to_config).to be_nil + expect(config.belongs_to_config).to eq nil config.belongs_to :posts - expect(config.belongs_to_config).to_not be_nil + expect(config.belongs_to_config).to_not eq nil end it "should set the target menu to the belongs to target" do diff --git a/spec/unit/scope_spec.rb b/spec/unit/scope_spec.rb index 69a6304f2fb..4ae77563381 100644 --- a/spec/unit/scope_spec.rb +++ b/spec/unit/scope_spec.rb @@ -60,12 +60,12 @@ describe '#scope_method' do subject { super().scope_method } - it { is_expected.to be_nil } + it { is_expected.to eq nil } end describe '#scope_block' do subject { super().scope_block } - it { is_expected.to be_nil } + it { is_expected.to eq nil } end end diff --git a/spec/unit/views/components/attributes_table_spec.rb b/spec/unit/views/components/attributes_table_spec.rb index b083a7f0f9c..0d393b994c0 100644 --- a/spec/unit/views/components/attributes_table_spec.rb +++ b/spec/unit/views/components/attributes_table_spec.rb @@ -170,7 +170,7 @@ end it "does not set id on the table" do - expect(table.attr(:id)).to be_nil + expect(table.attr(:id)).to eq nil end context "colgroup" do From 1fd4701cb5570845a986c6df990ff8e0c1ed8a54 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 20:31:51 -0600 Subject: [PATCH 0088/3836] fix test indentation --- spec/unit/views/components/blank_slate_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/unit/views/components/blank_slate_spec.rb b/spec/unit/views/components/blank_slate_spec.rb index c58bdaadd6b..6bacd0b95ac 100644 --- a/spec/unit/views/components/blank_slate_spec.rb +++ b/spec/unit/views/components/blank_slate_spec.rb @@ -11,17 +11,17 @@ describe '#tag_name' do subject { super().tag_name } - it { is_expected.to eql 'div' } + it { is_expected.to eql 'div' } end describe '#class_list' do subject { super().class_list } - it { is_expected.to include('blank_slate_container') } + it { is_expected.to include('blank_slate_container') } end describe '#content' do subject { super().content } - it { is_expected.to include 'There are no Posts yet. Create one' } + it { is_expected.to include 'There are no Posts yet. Create one' } end end end From e6b031e32a4431fbe82b07af89ced467d87e045c Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 20:33:58 -0600 Subject: [PATCH 0089/3836] `be_truthy` -> `eq true` for tests relying on `be_truthy` for `defined?` checks, simply check that it equals 'constant' --- features/step_definitions/filter_steps.rb | 2 +- .../authorization/authorization_adapter_spec.rb | 6 +++--- spec/unit/batch_actions/resource_spec.rb | 2 +- spec/unit/batch_actions/settings_spec.rb | 14 +++++++------- spec/unit/comments_spec.rb | 4 ++-- spec/unit/generators/install_spec.rb | 8 ++++---- spec/unit/helpers/collection_spec.rb | 4 ++-- spec/unit/namespace/register_page_spec.rb | 2 +- spec/unit/namespace/register_resource_spec.rb | 10 +++++----- spec/unit/pundit_adapter_spec.rb | 2 +- spec/unit/resource/naming_spec.rb | 2 +- spec/unit/resource_spec.rb | 2 +- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/features/step_definitions/filter_steps.rb b/features/step_definitions/filter_steps.rb index 71e2961c2b4..2ad7fe49d73 100644 --- a/features/step_definitions/filter_steps.rb +++ b/features/step_definitions/filter_steps.rb @@ -25,7 +25,7 @@ Then(/^I should( not)? have parameter "([^"]*)"( with value "([^"]*)")?$/) do |negative, key, compare_val, value| query = URI(page.current_url).query if query.nil? - expect(negative).to be_truthy + expect(negative).to eq true else params = Rack::Utils.parse_query query if compare_val diff --git a/spec/unit/authorization/authorization_adapter_spec.rb b/spec/unit/authorization/authorization_adapter_spec.rb index dfb3abd4d8c..b9fb0fece98 100644 --- a/spec/unit/authorization/authorization_adapter_spec.rb +++ b/spec/unit/authorization/authorization_adapter_spec.rb @@ -7,7 +7,7 @@ describe "#authorized?" do it "should always return true" do - expect(adapter.authorized?(:read, "Resource")).to be_truthy + expect(adapter.authorized?(:read, "Resource")).to eq true end end @@ -41,11 +41,11 @@ def authorized?(action, subject = nil) let(:adapter) { auth_class.new(double, double) } it "should match against a class" do - expect(adapter.authorized?(:read, String)).to be_truthy + expect(adapter.authorized?(:read, String)).to eq true end it 'should match against an instance' do - expect(adapter.authorized?(:read, "String")).to be_truthy + expect(adapter.authorized?(:read, "String")).to eq true end it 'should not match a different class' do diff --git a/spec/unit/batch_actions/resource_spec.rb b/spec/unit/batch_actions/resource_spec.rb index cae06ceee54..8120c1052c6 100644 --- a/spec/unit/batch_actions/resource_spec.rb +++ b/spec/unit/batch_actions/resource_spec.rb @@ -12,7 +12,7 @@ it "should have the default action by default" do expect(resource.batch_actions.size).to eq 1 - expect(resource.batch_actions.first.sym == :destroy).to be_truthy + expect(resource.batch_actions.first.sym == :destroy).to eq true end end diff --git a/spec/unit/batch_actions/settings_spec.rb b/spec/unit/batch_actions/settings_spec.rb index 7ca153dd541..7339c1f2eb4 100644 --- a/spec/unit/batch_actions/settings_spec.rb +++ b/spec/unit/batch_actions/settings_spec.rb @@ -15,26 +15,26 @@ it "should be settable to true" do app.batch_actions = true - expect(app.batch_actions).to be_truthy + expect(app.batch_actions).to eq true end it "should be an inheritable_setting" do app.batch_actions = true - expect(ns.batch_actions).to be_truthy + expect(ns.batch_actions).to eq true end it "should be settable at the namespace level" do app.batch_actions = true ns.batch_actions = false - expect(app.batch_actions).to be_truthy + expect(app.batch_actions).to eq true expect(ns.batch_actions).to be_falsey end it "should be settable at the resource level" do expect(post_resource.batch_actions_enabled?).to be_falsey post_resource.batch_actions = true - expect(post_resource.batch_actions_enabled?).to be_truthy + expect(post_resource.batch_actions_enabled?).to eq true end it "should inherit the setting on the resource from the namespace" do @@ -43,7 +43,7 @@ expect(post_resource.batch_actions).to be_empty post_resource.batch_actions = true - expect(post_resource.batch_actions_enabled?).to be_truthy + expect(post_resource.batch_actions_enabled?).to eq true expect(post_resource.batch_actions).to_not be_empty end @@ -51,11 +51,11 @@ ns.batch_actions = true post_resource.batch_actions = true - expect(post_resource.batch_actions_enabled?).to be_truthy + expect(post_resource.batch_actions_enabled?).to eq true expect(post_resource.batch_actions).to_not be_empty post_resource.batch_actions = nil - expect(post_resource.batch_actions_enabled?).to be_truthy # inherited from namespace + expect(post_resource.batch_actions_enabled?).to eq true # inherited from namespace expect(post_resource.batch_actions).to_not be_empty end end diff --git a/spec/unit/comments_spec.rb b/spec/unit/comments_spec.rb index d066fc16c86..93c7d9cb421 100644 --- a/spec/unit/comments_spec.rb +++ b/spec/unit/comments_spec.rb @@ -159,7 +159,7 @@ it "should have comments when the namespace allows comments" do ns = ActiveAdmin::Namespace.new(application, :admin) ns.comments = true - expect(ns.comments?).to be_truthy + expect(ns.comments?).to eq true end it "should not have comments when the namespace does not allow comments" do @@ -176,7 +176,7 @@ resource = ActiveAdmin::Resource.new(ns, Post) expect(resource.comments).to eq nil resource.comments = true - expect(resource.comments).to be_truthy + expect(resource.comments).to eq true end it "should disable comments if set to false" do ns = ActiveAdmin::Namespace.new(application, :admin) diff --git a/spec/unit/generators/install_spec.rb b/spec/unit/generators/install_spec.rb index 868d7460897..6b170a31a62 100644 --- a/spec/unit/generators/install_spec.rb +++ b/spec/unit/generators/install_spec.rb @@ -5,19 +5,19 @@ it "active_admin.scss" do path = Rails.root + "app/assets/stylesheets/active_admin.scss" - expect(File.exists? path).to be_truthy + expect(File.exists? path).to eq true end it "active_admin.js.coffee" do - expect(File.exists?(Rails.root + "app/assets/javascripts/active_admin.js.coffee")).to be_truthy + expect(File.exists?(Rails.root + "app/assets/javascripts/active_admin.js.coffee")).to eq true end it "the dashboard" do - expect(File.exists?(Rails.root + "app/admin/dashboard.rb")).to be_truthy + expect(File.exists?(Rails.root + "app/admin/dashboard.rb")).to eq true end it "the initializer" do - expect(File.exists?(Rails.root + "config/initializers/active_admin.rb")).to be_truthy + expect(File.exists?(Rails.root + "config/initializers/active_admin.rb")).to eq true end end diff --git a/spec/unit/helpers/collection_spec.rb b/spec/unit/helpers/collection_spec.rb index b8915c250c6..9db2bbfb502 100644 --- a/spec/unit/helpers/collection_spec.rb +++ b/spec/unit/helpers/collection_spec.rb @@ -45,7 +45,7 @@ def collection; Post.where(title: "An other post"); end describe "#collection_is_empty?" do it "should return true when the collection is empty" do - expect(collection_is_empty?(Post.where(title: "Non existing post"))).to be_truthy + expect(collection_is_empty?(Post.where(title: "Non existing post"))).to eq true end it "should return false when the collection is not empty" do @@ -59,7 +59,7 @@ def collection; Post.where(nil); end def collection; Post.where(title: "Non existing post"); end - expect(collection_is_empty?).to be_truthy + expect(collection_is_empty?).to eq true end end end diff --git a/spec/unit/namespace/register_page_spec.rb b/spec/unit/namespace/register_page_spec.rb index 81ef7abff93..5de0b6a1e80 100644 --- a/spec/unit/namespace/register_page_spec.rb +++ b/spec/unit/namespace/register_page_spec.rb @@ -15,7 +15,7 @@ end it "should create a new controller in the default namespace" do - expect(defined?(Admin::StatusController)).to be_truthy + expect(defined?(Admin::StatusController)).to eq 'constant' end it "should create a menu item" do diff --git a/spec/unit/namespace/register_resource_spec.rb b/spec/unit/namespace/register_resource_spec.rb index 17d232b29f8..7f940b56884 100644 --- a/spec/unit/namespace/register_resource_spec.rb +++ b/spec/unit/namespace/register_resource_spec.rb @@ -18,11 +18,11 @@ end it "should create a new controller in the default namespace" do - expect(defined?(Admin::CategoriesController)).to be_truthy + expect(defined?(Admin::CategoriesController)).to eq 'constant' end skip "should not create the dashboard controller" do - defined?(Admin::DashboardController).to_not be_truthy + defined?(Admin::DashboardController).to_not eq 'constant' end it "should create a menu item" do @@ -49,7 +49,7 @@ module ::Mock; class Resource; def self.has_many(arg1, arg2); end; end; end expect(namespace.resources.keys).to include('Mock::Resource') end it "should create a new controller in the default namespace" do - expect(defined?(Admin::MockResourcesController)).to be_truthy + expect(defined?(Admin::MockResourcesController)).to eq 'constant' end it "should create a menu item" do expect(menu["Mock Resources"]).to be_an_instance_of(ActiveAdmin::MenuItem) @@ -146,14 +146,14 @@ module ::Mock; class Resource; def self.has_many(arg1, arg2); end; end; end it "should be namespaced" do namespace = ActiveAdmin::Namespace.new(application, :one) namespace.register Category - expect(defined?(One::CategoriesController)).to be_truthy + expect(defined?(One::CategoriesController)).to eq 'constant' end end context "when not namespaced" do it "should not be namespaced" do namespace = ActiveAdmin::Namespace.new(application, :two) namespace.register Category - expect(defined?(Two::CategoriesController)).to be_truthy + expect(defined?(Two::CategoriesController)).to eq 'constant' end end end # describe "dashboard controller name" diff --git a/spec/unit/pundit_adapter_spec.rb b/spec/unit/pundit_adapter_spec.rb index a514e49ed94..abeb6ac23f3 100644 --- a/spec/unit/pundit_adapter_spec.rb +++ b/spec/unit/pundit_adapter_spec.rb @@ -65,7 +65,7 @@ def resolve it "works well with method_missing" do allow(auth).to receive(:retrieve_policy).and_return(DefaultPolicy.new(double, double)) expect(auth.authorized?(:foo_no)).to be_falsey - expect(auth.authorized?(:foo_yes)).to be_truthy + expect(auth.authorized?(:foo_yes)).to eq true expect(auth.authorized?(:bar_yes)).to be_falsey end diff --git a/spec/unit/resource/naming_spec.rb b/spec/unit/resource/naming_spec.rb index 727610eb777..81d06c88221 100644 --- a/spec/unit/resource/naming_spec.rb +++ b/spec/unit/resource/naming_spec.rb @@ -110,7 +110,7 @@ module NoActiveModel class Resource; end; end [:==, :===, :eql?].each do |method| it "are equivalent when compared with #{method}" do - expect(resource_name.public_send(method, duplicate_resource_name)).to be_truthy + expect(resource_name.public_send(method, duplicate_resource_name)).to eq true end end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index 327f7a0c290..60281ee7492 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -218,7 +218,7 @@ def config(options = {}) context "when breadcrumb is set" do context "when set to true" do before { config.breadcrumb = true } - it { is_expected.to be_truthy } + it { is_expected.to eq true } end context "when set to false" do From 44af5757d34df99be93666d52b0ee659f0b5f927 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 20:34:55 -0600 Subject: [PATCH 0090/3836] `be_falsey` -> `eq false` --- .../unit/authorization/authorization_adapter_spec.rb | 4 ++-- spec/unit/batch_actions/settings_spec.rb | 12 ++++++------ spec/unit/comments_spec.rb | 4 ++-- spec/unit/helpers/collection_spec.rb | 4 ++-- spec/unit/pundit_adapter_spec.rb | 4 ++-- spec/unit/resource_spec.rb | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/unit/authorization/authorization_adapter_spec.rb b/spec/unit/authorization/authorization_adapter_spec.rb index b9fb0fece98..17c3a075781 100644 --- a/spec/unit/authorization/authorization_adapter_spec.rb +++ b/spec/unit/authorization/authorization_adapter_spec.rb @@ -49,11 +49,11 @@ def authorized?(action, subject = nil) end it 'should not match a different class' do - expect(adapter.authorized?(:read, Hash)).to be_falsey + expect(adapter.authorized?(:read, Hash)).to eq false end it 'should not match a different instance' do - expect(adapter.authorized?(:read, {})).to be_falsey + expect(adapter.authorized?(:read, {})).to eq false end end diff --git a/spec/unit/batch_actions/settings_spec.rb b/spec/unit/batch_actions/settings_spec.rb index 7339c1f2eb4..4cb186169cb 100644 --- a/spec/unit/batch_actions/settings_spec.rb +++ b/spec/unit/batch_actions/settings_spec.rb @@ -8,9 +8,9 @@ it "should be disabled globally by default" do # Note: the default initializer would set it to true - expect(app.batch_actions).to be_falsey - expect(ns.batch_actions).to be_falsey - expect(post_resource.batch_actions_enabled?).to be_falsey + expect(app.batch_actions).to eq false + expect(ns.batch_actions).to eq false + expect(post_resource.batch_actions_enabled?).to eq false end it "should be settable to true" do @@ -28,18 +28,18 @@ ns.batch_actions = false expect(app.batch_actions).to eq true - expect(ns.batch_actions).to be_falsey + expect(ns.batch_actions).to eq false end it "should be settable at the resource level" do - expect(post_resource.batch_actions_enabled?).to be_falsey + expect(post_resource.batch_actions_enabled?).to eq false post_resource.batch_actions = true expect(post_resource.batch_actions_enabled?).to eq true end it "should inherit the setting on the resource from the namespace" do ns.batch_actions = false - expect(post_resource.batch_actions_enabled?).to be_falsey + expect(post_resource.batch_actions_enabled?).to eq false expect(post_resource.batch_actions).to be_empty post_resource.batch_actions = true diff --git a/spec/unit/comments_spec.rb b/spec/unit/comments_spec.rb index 93c7d9cb421..0272181f95c 100644 --- a/spec/unit/comments_spec.rb +++ b/spec/unit/comments_spec.rb @@ -165,7 +165,7 @@ it "should not have comments when the namespace does not allow comments" do ns = ActiveAdmin::Namespace.new(application, :admin) ns.comments = false - expect(ns.comments?).to be_falsey + expect(ns.comments?).to eq false end end end @@ -182,7 +182,7 @@ ns = ActiveAdmin::Namespace.new(application, :admin) resource = ActiveAdmin::Resource.new(ns, Post) resource.comments = false - expect(resource.comments?).to be_falsey + expect(resource.comments?).to eq false end end end diff --git a/spec/unit/helpers/collection_spec.rb b/spec/unit/helpers/collection_spec.rb index 9db2bbfb502..77e3b5b2008 100644 --- a/spec/unit/helpers/collection_spec.rb +++ b/spec/unit/helpers/collection_spec.rb @@ -49,13 +49,13 @@ def collection; Post.where(title: "An other post"); end end it "should return false when the collection is not empty" do - expect(collection_is_empty?(Post.where(title: "A post"))).to be_falsey + expect(collection_is_empty?(Post.where(title: "A post"))).to eq false end it "should take the defined collection by default" do def collection; Post.where(nil); end - expect(collection_is_empty?).to be_falsey + expect(collection_is_empty?).to eq false def collection; Post.where(title: "Non existing post"); end diff --git a/spec/unit/pundit_adapter_spec.rb b/spec/unit/pundit_adapter_spec.rb index abeb6ac23f3..1f02c66c9e1 100644 --- a/spec/unit/pundit_adapter_spec.rb +++ b/spec/unit/pundit_adapter_spec.rb @@ -64,9 +64,9 @@ def resolve it "works well with method_missing" do allow(auth).to receive(:retrieve_policy).and_return(DefaultPolicy.new(double, double)) - expect(auth.authorized?(:foo_no)).to be_falsey + expect(auth.authorized?(:foo_no)).to eq false expect(auth.authorized?(:foo_yes)).to eq true - expect(auth.authorized?(:bar_yes)).to be_falsey + expect(auth.authorized?(:bar_yes)).to eq false end context 'when Pundit is unable to find policy scope' do diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index 60281ee7492..ef35024f637 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -223,7 +223,7 @@ def config(options = {}) context "when set to false" do before { config.breadcrumb = false } - it { is_expected.to be_falsey } + it { is_expected.to eq false } end end end From ac8e77b7d64fe45c23589b8c809b9dd3b4858aad Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 13 Feb 2016 20:41:47 -0600 Subject: [PATCH 0091/3836] fix local dev after Travis fix e2ba34004cb6fc8640455233557734ea3a642290 fixed Travis, but broke local dev because the quotes are treated literally. This is the error: Illformed requirement ["\"> 5.x\""]. Bundler cannot continue. --- spec/support/detect_rails_version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/detect_rails_version.rb b/spec/support/detect_rails_version.rb index 59cde7ff8c8..67895fba372 100644 --- a/spec/support/detect_rails_version.rb +++ b/spec/support/detect_rails_version.rb @@ -7,7 +7,7 @@ require 'yaml' filename = File.expand_path("../../../.travis.yml", __FILE__) TRAVIS_CONFIG = YAML.load_file filename - TRAVIS_RAILS_VERSIONS = TRAVIS_CONFIG['env']['matrix'].grep(/RAILS=(.*)/){ $1 } + TRAVIS_RAILS_VERSIONS = TRAVIS_CONFIG['env']['matrix'].grep(/RAILS=(.*)/){ $1 }.map{ |v| v.delete('"') } end DEFAULT_RAILS_VERSION ||= TRAVIS_RAILS_VERSIONS.last From e6a81e8da7407ec46cfdfcf9a1c78306ddca82c6 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 14 Feb 2016 11:40:38 -0600 Subject: [PATCH 0092/3836] fix script/local - Shellwords had to be explicitly required - File.exists? breaks on the escaped string --- script/local | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/script/local b/script/local index 8ecda7cd103..75bc3dd7143 100755 --- a/script/local +++ b/script/local @@ -1,5 +1,6 @@ #!/usr/bin/env ruby +require 'shellwords' require File.expand_path('../../spec/support/detect_rails_version', __FILE__) unless ARGV[0] @@ -21,14 +22,14 @@ end # Set up some variables rails_version = detect_rails_version! -test_app_dir = ".test-rails-apps" -test_app_path = "#{test_app_dir}/test-rails-app-#{Shellwords.escape rails_version}" +dir = ".test-rails-apps" +path = "#{dir}/test-rails-app-#{rails_version}" # Ensure .test-rails-apps is created -system "mkdir #{test_app_dir}" unless File.exists?(test_app_dir) +system "mkdir #{dir}" unless File.exists?(dir) # Create the sample rails app if it doesn't already exist -unless File.exists? test_app_path +unless File.exists? path args = %w[ -m\ spec/support/rails_template_with_data.rb --skip-gemfile @@ -37,12 +38,12 @@ unless File.exists? test_app_path --skip-turbolinks --skip-test-unit ] - system "RAILS='#{rails_version}' bundle exec rails new #{test_app_path} #{args.join ' '}" + system "RAILS='#{rails_version}' bundle exec rails new #{Shellwords.escape path} #{args.join ' '}" end # Link this rails app system "rm test-rails-app" -system "ln -s #{test_app_path} test-rails-app" +system "ln -s #{Shellwords.escape path} test-rails-app" # If it's a rails command, auto add the rails script RAILS_COMMANDS = %w{generate console server dbconsole g c s runner} From 80cc7b0eba5f0b04f4a7a8a76e09ca59268eb3a0 Mon Sep 17 00:00:00 2001 From: Marco Mastrodonato Date: Mon, 15 Feb 2016 11:54:35 +0100 Subject: [PATCH 0093/3836] Forms tags are now generated with boilerplate option set to true --- lib/active_admin/generators/boilerplate.rb | 8 ++++++++ lib/generators/active_admin/resource/templates/admin.rb | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/lib/active_admin/generators/boilerplate.rb b/lib/active_admin/generators/boilerplate.rb index 26de57c2f76..f1d963e27e0 100644 --- a/lib/active_admin/generators/boilerplate.rb +++ b/lib/active_admin/generators/boilerplate.rb @@ -32,6 +32,14 @@ def filters def filter(name) "# filter :#{name.gsub(/_id$/, '')}" end + + def form_inputs + attributes.reject{|a| %w(id created_at updated_at).include? a}.map{ |a| form_input(a) }.join("\n") + end + + def form_input(name) + "# f.input :#{name.gsub(/_id$/, '')}" + end end end end diff --git a/lib/generators/active_admin/resource/templates/admin.rb b/lib/generators/active_admin/resource/templates/admin.rb index c4105241760..b0ca2cf1908 100644 --- a/lib/generators/active_admin/resource/templates/admin.rb +++ b/lib/generators/active_admin/resource/templates/admin.rb @@ -35,5 +35,11 @@ # end # Add or remove fields to toggle their visibility in the form +# form do |f| +# f.inputs do +<%= @boilerplate.form_inputs %> +# end +# f.actions +# end <% end %> end From b20fd04e992f721f49557f4dc59c7da3a732ba68 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Wed, 17 Feb 2016 19:08:57 -0600 Subject: [PATCH 0094/3836] #4267: update boilerplate permit_params example --- lib/generators/active_admin/resource/templates/admin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/active_admin/resource/templates/admin.rb b/lib/generators/active_admin/resource/templates/admin.rb index b0ca2cf1908..a012e6a738e 100644 --- a/lib/generators/active_admin/resource/templates/admin.rb +++ b/lib/generators/active_admin/resource/templates/admin.rb @@ -9,7 +9,7 @@ # # permit_params do # permitted = [:permitted, :attributes] -# permitted << :other if resource.something? +# permitted << :other if params[:action] == 'create' && current_user.admin? # permitted # end <% end %> From dbca117aad30481e399221d0f87e47dac021fc76 Mon Sep 17 00:00:00 2001 From: Jeremy Ebler Date: Thu, 4 Jun 2015 23:13:01 -0700 Subject: [PATCH 0095/3836] Allow menu options to be passed into ActiveAdmin::Comment --- lib/active_admin/orm/active_record/comments.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/orm/active_record/comments.rb b/lib/active_admin/orm/active_record/comments.rb index 9d7e7db4c5c..df7e765e9d5 100644 --- a/lib/active_admin/orm/active_record/comments.rb +++ b/lib/active_admin/orm/active_record/comments.rb @@ -8,6 +8,7 @@ ActiveAdmin::Application.inheritable_setting :show_comments_in_menu, true ActiveAdmin::Application.inheritable_setting :comments_registration_name, 'Comment' ActiveAdmin::Application.inheritable_setting :comments_order, "created_at ASC" +ActiveAdmin::Application.inheritable_setting :comments_menu, {} # Insert helper modules ActiveAdmin::Namespace.send :include, ActiveAdmin::Comments::NamespaceHelper @@ -23,7 +24,11 @@ namespace.register ActiveAdmin::Comment, as: namespace.comments_registration_name do actions :index, :show, :create, :destroy - menu false unless namespace.comments && namespace.show_comments_in_menu + if namespace.comments && namespace.show_comments_in_menu + menu namespace.comments_menu + elsif !namespace.comments || !namespace.show_comments_in_menu + menu false + end config.comments = false # Don't allow comments on comments config.batch_actions = false # The default destroy batch action isn't showing up anyway... From faff3bd3192bd5709e1877b3f3027000e9762a84 Mon Sep 17 00:00:00 2001 From: Jeremy Ebler Date: Thu, 4 Jun 2015 23:26:45 -0700 Subject: [PATCH 0096/3836] Add comment_menu example to initializer template --- .../active_admin/install/templates/active_admin.rb.erb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/generators/active_admin/install/templates/active_admin.rb.erb b/lib/generators/active_admin/install/templates/active_admin.rb.erb index caca3cff280..083d431249c 100644 --- a/lib/generators/active_admin/install/templates/active_admin.rb.erb +++ b/lib/generators/active_admin/install/templates/active_admin.rb.erb @@ -130,6 +130,9 @@ ActiveAdmin.setup do |config| # You can change the order for the comments and you can change the column # to be used for ordering # config.comments_order = 'created_at ASC' + # + # You can customize the comment menu + # config.comments_menu = { parent: 'Admins', priority: 1 } # == Batch Actions # From 75773a0f38aebf69d63e0b659d6ed67c04b00fd6 Mon Sep 17 00:00:00 2001 From: Darren Cheng Date: Tue, 10 Nov 2015 14:28:46 -0800 Subject: [PATCH 0097/3836] Update customizable comment menu settings. --- CHANGELOG.md | 2 ++ docs/1-general-configuration.md | 22 +++++++++++++++++++ .../orm/active_record/comments.rb | 9 ++------ .../install/templates/active_admin.rb.erb | 12 +++++----- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8057afe2ac7..e575aba7b9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * JavaScript `window.AA` has been removed, use `window.ActiveAdmin` [#3606][] by [@timoschilling][] * `f.form_buffers` has been removed [#3486][] by [@varyonic][] * Iconic has been removed [#3553][] by [@timoschilling][] +* `config.show_comments_in_menu` has been removed [#4187][] by [@drn][] ### Enhancements @@ -45,6 +46,7 @@ ```ruby index download_links: ->{ can?(:view_all_download_links) || [:pdf] } ``` +* Comments menu can be customized via configuration passed to `config.comments_menu` [#4187][] by [@drn][] ### Security Fixes diff --git a/docs/1-general-configuration.md b/docs/1-general-configuration.md index 6cb1ba8a754..a7798312088 100644 --- a/docs/1-general-configuration.md +++ b/docs/1-general-configuration.md @@ -129,6 +129,28 @@ ActiveAdmin.register Post do end ``` +You can change the name under which comments are registered: + +```ruby +config.comments_registration_name = 'AdminComment' +``` + +You can change the order for the comments and you can change the column to be +used for ordering: +```ruby +config.comments_order = 'created_at ASC' +``` + +You can disable the menu item for the comments index page: +```ruby +config.comments_menu = false +``` + +You can customize the comment menu: +```ruby +config.comments_menu = { parent: 'Admin', priority: 1 } +``` + ## Utility Navigation The "utility navigation" shown at the top right normally shows the current user diff --git a/lib/active_admin/orm/active_record/comments.rb b/lib/active_admin/orm/active_record/comments.rb index df7e765e9d5..5973fc2ed8f 100644 --- a/lib/active_admin/orm/active_record/comments.rb +++ b/lib/active_admin/orm/active_record/comments.rb @@ -5,10 +5,9 @@ # Add the comments configuration ActiveAdmin::Application.inheritable_setting :comments, true -ActiveAdmin::Application.inheritable_setting :show_comments_in_menu, true ActiveAdmin::Application.inheritable_setting :comments_registration_name, 'Comment' ActiveAdmin::Application.inheritable_setting :comments_order, "created_at ASC" -ActiveAdmin::Application.inheritable_setting :comments_menu, {} +ActiveAdmin::Application.inheritable_setting :comments_menu, {} # Insert helper modules ActiveAdmin::Namespace.send :include, ActiveAdmin::Comments::NamespaceHelper @@ -24,11 +23,7 @@ namespace.register ActiveAdmin::Comment, as: namespace.comments_registration_name do actions :index, :show, :create, :destroy - if namespace.comments && namespace.show_comments_in_menu - menu namespace.comments_menu - elsif !namespace.comments || !namespace.show_comments_in_menu - menu false - end + menu namespace.comments ? namespace.comments_menu : false config.comments = false # Don't allow comments on comments config.batch_actions = false # The default destroy batch action isn't showing up anyway... diff --git a/lib/generators/active_admin/install/templates/active_admin.rb.erb b/lib/generators/active_admin/install/templates/active_admin.rb.erb index 083d431249c..8fc53b35c44 100644 --- a/lib/generators/active_admin/install/templates/active_admin.rb.erb +++ b/lib/generators/active_admin/install/templates/active_admin.rb.erb @@ -121,18 +121,18 @@ ActiveAdmin.setup do |config| # You can completely disable comments: # config.comments = false # - # You can disable the menu item for the comments index page: - # config.show_comments_in_menu = false - # # You can change the name under which comments are registered: # config.comments_registration_name = 'AdminComment' # # You can change the order for the comments and you can change the column - # to be used for ordering + # to be used for ordering: # config.comments_order = 'created_at ASC' # - # You can customize the comment menu - # config.comments_menu = { parent: 'Admins', priority: 1 } + # You can disable the menu item for the comments index page: + # config.comments_menu = false + # + # You can customize the comment menu: + # config.comments_menu = { parent: 'Admin', priority: 1 } # == Batch Actions # From cf5e013910ecd81329d66d273ba28d3b06769ef2 Mon Sep 17 00:00:00 2001 From: Giuseppe Date: Thu, 10 Mar 2016 09:24:55 +0100 Subject: [PATCH 0098/3836] typo fix --- docs/14-gotchas.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index cc2cf729250..84f1ce4b40c 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -19,7 +19,7 @@ For more information see the following post: ## Helpers -There are two knowing gotchas with helpers. This hopefully will help you to +There are two known gotchas with helpers. This hopefully will help you to find a solution. ### Helpers are not reloading in development From 1c85c5654a2ce1d43d4c64d98b928ff133d46406 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Mon, 14 Mar 2016 18:36:51 -0500 Subject: [PATCH 0099/3836] DatabaseCleaner/database_cleaner#415 has been merged --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 1dc46b0d23a..e5a426841a6 100644 --- a/Gemfile +++ b/Gemfile @@ -19,7 +19,7 @@ if rails_version == '> 5.x' gem 'formtastic', github: 'justinfrench/formtastic' gem 'activemodel-serializers-xml', github: 'rails/activemodel-serializers-xml' # drapergem/draper#697 gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' - gem 'database_cleaner', github: 'pschambacher/database_cleaner', branch: 'rails5.0', ref: '8dd9fa4' + gem 'database_cleaner', github: 'DatabaseCleaner/database_cleaner' gem 'activerecord-jdbc-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: :jruby end From 410126322f1be505183f20cefebf83f7fe180324 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 13 Mar 2016 12:04:53 -0500 Subject: [PATCH 0100/3836] localize_format shouldn't be an inheritable setting --- lib/active_admin/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/application.rb b/lib/active_admin/application.rb index 544f92a4113..ff10e023741 100644 --- a/lib/active_admin/application.rb +++ b/lib/active_admin/application.rb @@ -109,7 +109,7 @@ def initialize inheritable_setting :flash_keys_to_except, ['timedout'] # Set default localize format for Date/Time values - inheritable_setting :localize_format, :long + setting :localize_format, :long # Include association filters by default inheritable_setting :include_default_association_filters, true From f63d6fca480543a0c6d159ce8398c9de49b6ea4d Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Mon, 14 Mar 2016 18:55:13 -0500 Subject: [PATCH 0101/3836] make routing tests more consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit they relied too much on previous tests that ran, and wouldn’t reset to a clean environment after they were finished --- spec/unit/resource/routes_spec.rb | 6 +++++- spec/unit/routing_spec.rb | 33 ++++++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 478ab764a5b..a5957bf7f4b 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -2,7 +2,11 @@ module ActiveAdmin describe Resource::Routes do - before { load_defaults! } + + after :all do + load_defaults! + reload_routes! + end describe "route names" do context "when in the admin namespace" do diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index db8f32fae6d..1bb77fac0fd 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -9,6 +9,11 @@ reload_routes! end + after :all do + load_defaults! + reload_routes! + end + it "should only have the namespaces necessary for route testing" do expect(ActiveAdmin.application.namespaces.names).to eq [:admin, :root] end @@ -155,25 +160,25 @@ it "should route to the page under /admin" do expect(admin_chocolate_i_love_you_path).to eq "/admin/chocolate_i_love_you" end + end - context "when in the root namespace" do - before(:each) do - load_resources { ActiveAdmin.register_page("Chocolate I lØve You!", namespace: false) } - end + context "when in the root namespace" do + before(:each) do + load_resources { ActiveAdmin.register_page("Chocolate I lØve You!", namespace: false) } + end - it "should route to page under /" do - expect(chocolate_i_love_you_path).to eq "/chocolate_i_love_you" - end + it "should route to page under /" do + expect(chocolate_i_love_you_path).to eq "/chocolate_i_love_you" end + end - context "when singular page name" do - before(:each) do - load_resources { ActiveAdmin.register_page("Log") } - end + context "when singular page name" do + before(:each) do + load_resources { ActiveAdmin.register_page("Log") } + end - it "should not inject _index_ into the route name" do - expect(admin_log_path).to eq "/admin/log" - end + it "should not inject _index_ into the route name" do + expect(admin_log_path).to eq "/admin/log" end end end From 5f8e27dc31b25ae22cb2b68fd770a8b54602d1c7 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Mon, 14 Mar 2016 19:17:53 -0500 Subject: [PATCH 0102/3836] don't run JS tests on OS X if Java isn't installed --- spec/requests/javascript_spec.rb | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/spec/requests/javascript_spec.rb b/spec/requests/javascript_spec.rb index d8099b065a8..8d41b4edb95 100644 --- a/spec/requests/javascript_spec.rb +++ b/spec/requests/javascript_spec.rb @@ -1,20 +1,22 @@ require 'rails_helper' require 'jslint' +require 'rbconfig' -%x[which java] -if $? == 0 # Only run the JS Lint test if Java is installed - describe "Javascript", :type => :request do - before do - @lint = JSLint::Lint.new( - paths: ['public/javascripts/**/*.js'], - exclude_paths: ['public/javascripts/vendor/**/*.js'], - config_path: 'spec/support/jslint.yml' - ) - end +# OSX has its own java executable that opens a prompt to install Java 💩 +# However this java_home executable returns an error code without opening the prompt ✅ +RbConfig::CONFIG['host_os'].include?('darwin') ? `/usr/libexec/java_home` : `which java` +java_installed = $?.success? - it "should not have any syntax errors" do - @lint.run - end +describe 'Javascript', type: :request, if: java_installed do + let(:lint) { + JSLint::Lint.new \ + paths: ['public/javascripts/**/*.js'], + exclude_paths: ['public/javascripts/vendor/**/*.js'], + config_path: 'spec/support/jslint.yml' + } + + it 'should not have any syntax errors' do + lint.run end end From 3b86e9768f0fe54d161cdf66bdf9692966fb4e40 Mon Sep 17 00:00:00 2001 From: Luciano Sousa Date: Fri, 18 Mar 2016 16:46:32 -0300 Subject: [PATCH 0103/3836] add builder with ActiveAdmin::FormBuilder section This is a useful example of ActiveAdmin power to build custom forms and are not explained in any other easy place. Hope this help people like helped myself today. ;) --- docs/5-forms.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/5-forms.md b/docs/5-forms.md index 13ee7d691e3..7f999996f7f 100644 --- a/docs/5-forms.md +++ b/docs/5-forms.md @@ -60,6 +60,18 @@ end This is a regular Rails partial so any template engine may be used. +You can also use the `ActiveAdmin::FormBuilder` as builder in your Formtastic Form for use the same helpers are used in the admin file: + +```ruby + = semantic_form_for [:admin, @post], builder: ActiveAdmin::FormBuilder do |f| + = f.inputs "Details" do + = f.input :title + - f.has_many :taggings, sortable: :position, sortable_start: 1 do |t| + - t.input :tag + = f.actions + +``` + ## Nested Resources You can create forms with nested models using the `has_many` method, even if your model uses `has_one`: From 8169e88a36f022ab842e7c327cf73fa5dabf54c6 Mon Sep 17 00:00:00 2001 From: Rein Aris Date: Mon, 21 Mar 2016 14:04:39 +0100 Subject: [PATCH 0104/3836] Improved layout for boolean fields --- app/assets/stylesheets/active_admin/_forms.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/active_admin/_forms.scss b/app/assets/stylesheets/active_admin/_forms.scss index fe5d45e8349..93832db678c 100644 --- a/app/assets/stylesheets/active_admin/_forms.scss +++ b/app/assets/stylesheets/active_admin/_forms.scss @@ -180,7 +180,7 @@ form { /* Boolean Field */ &.boolean { - height: 1.1em; + min-height: 1.1em; label { width: 80%; padding-left:20%; From 3efb359533df46e76bb4355a02ad31e727fb0da3 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Mon, 14 Mar 2016 19:20:40 -0500 Subject: [PATCH 0105/3836] Standardize value formatting for attributes_table and table_for --- features/show/default_content.feature | 2 +- features/strong_parameters.feature | 6 +- .../view_helpers/display_helper.rb | 31 ++++ .../views/components/attributes_table.rb | 20 +-- .../views/components/table_for.rb | 31 +--- lib/active_admin/views/index_as_table.rb | 4 +- spec/unit/auto_link_spec.rb | 2 +- spec/unit/view_helpers/display_helper_spec.rb | 165 ++++++++++++++++++ spec/unit/view_helpers/display_name_spec.rb | 71 -------- spec/unit/views/components/table_for_spec.rb | 21 ++- 10 files changed, 226 insertions(+), 127 deletions(-) create mode 100644 spec/unit/view_helpers/display_helper_spec.rb delete mode 100644 spec/unit/view_helpers/display_name_spec.rb diff --git a/features/show/default_content.feature b/features/show/default_content.feature index e2d8fbd7e4c..ebc692d677b 100644 --- a/features/show/default_content.feature +++ b/features/show/default_content.feature @@ -14,7 +14,7 @@ Feature: Show - Default Content And I should see the attribute "Body" with "Empty" And I should see the attribute "Created At" with a nicely formatted datetime And I should see the attribute "Author" with "Jane Doe" - And I should see the attribute "Starred" with "false" + And I should see the attribute "Starred" with "No" And I should see an action item button "Delete Post" And I should see an action item button "Edit Post" diff --git a/features/strong_parameters.feature b/features/strong_parameters.feature index 807e2fbc8be..4a25a42fb51 100644 --- a/features/strong_parameters.feature +++ b/features/strong_parameters.feature @@ -32,7 +32,7 @@ Feature: Strong Params Then I should see "Post was successfully updated." And I should see the attribute "Title" with "Hello World from update" And I should see the attribute "Author" with "John Doe" - And I should see the attribute "Starred" with "true" + And I should see the attribute "Starred" with "Yes" Scenario: Dynamic permitted parameters Given a configuration of: @@ -53,7 +53,7 @@ Feature: Strong Params Then I should see "Post was successfully updated." And I should see the attribute "Title" with "Hello World from update" And I should see the attribute "Author" with "John Doe" - And I should see the attribute "Starred" with "true" + And I should see the attribute "Starred" with "Yes" Scenario: Should not update parameters that are not declared as permitted Given a configuration of: @@ -70,4 +70,4 @@ Feature: Strong Params Then I should see "Post was successfully updated." And I should see the attribute "Title" with "Hello World from update" And I should see the attribute "Author" with "John Doe" - And the attribute "Starred" should be empty + And I should see the attribute "Starred" with "No" diff --git a/lib/active_admin/view_helpers/display_helper.rb b/lib/active_admin/view_helpers/display_helper.rb index 35bde812a90..cec3dfa981a 100644 --- a/lib/active_admin/view_helpers/display_helper.rb +++ b/lib/active_admin/view_helpers/display_helper.rb @@ -40,6 +40,25 @@ def association_methods_for(resource) resource.class.reflect_on_all_associations.map(&:name) end + def format_attribute(resource, attr) + value = find_value resource, attr + value = pretty_format value if attr.is_a? Symbol + value = Arbre::Context.new{ status_tag value } if boolean_attr? resource, attr + value + end + + def find_value(resource, attr) + if attr.is_a? Proc + attr.call resource + elsif attr =~ /\A(.+)_id\z/ && reflection_for(resource, $1.to_sym) + resource.public_send $1 + elsif resource.respond_to? attr + resource.public_send attr + elsif resource.respond_to? :[] + resource[attr] + end + end + # Attempts to create a human-readable string for any object def pretty_format(object) case object @@ -56,6 +75,18 @@ def pretty_format(object) end end end + + def reflection_for(resource, method) + klass = resource.class + klass.reflect_on_association method if klass.respond_to? :reflect_on_association + end + + def boolean_attr?(resource, attr) + if resource.class.respond_to? :columns_hash + column = resource.class.columns_hash[attr.to_s] and column.type == :boolean + end + end + end end end diff --git a/lib/active_admin/views/components/attributes_table.rb b/lib/active_admin/views/components/attributes_table.rb index 7a80361ca32..cfba14d9de6 100644 --- a/lib/active_admin/views/components/attributes_table.rb +++ b/lib/active_admin/views/components/attributes_table.rb @@ -79,24 +79,10 @@ def empty_value end def content_for(record, attr) - value = pretty_format find_attr_value(record, attr) + value = format_attribute record, attr value.blank? && current_arbre_element.children.to_s.empty? ? empty_value : value - end - - def find_attr_value(record, attr) - if attr.is_a?(Proc) - attr.call(record) - elsif attr =~ /\A(.+)_id\z/ && reflection_for(record.class, $1.to_sym) - record.public_send $1 - elsif record.respond_to? attr - record.public_send attr - elsif record.respond_to? :[] - record[attr] - end - end - - def reflection_for(klass, method) - klass.reflect_on_association method if klass.respond_to? :reflect_on_association + # Don't add the same Arbre twice, while still allowing format_attribute to call status_tag + current_arbre_element << value unless current_arbre_element.children.include? value end def single_record? diff --git a/lib/active_admin/views/components/table_for.rb b/lib/active_admin/views/components/table_for.rb index 9f5a068c551..68a0a972a3b 100644 --- a/lib/active_admin/views/components/table_for.rb +++ b/lib/active_admin/views/components/table_for.rb @@ -39,9 +39,9 @@ def column(*args, &block) end # Add a table cell for each item - @collection.each_with_index do |item, i| - within @tbody.children[i] do - build_table_cell col, item + @collection.each_with_index do |resource, index| + within @tbody.children[index] do + build_table_cell col, resource end end end @@ -96,28 +96,11 @@ def build_table_body end end - def build_table_cell(col, item) + def build_table_cell(col, resource) td class: col.html_class do - render_data col.data, item - end - end - - def render_data(data, item) - value = if data.is_a? Proc - data.call item - elsif item.respond_to? data - item.public_send data - elsif item.respond_to? :[] - item[data] - end - value = pretty_format(value) if data.is_a?(Symbol) - value = status_tag value if is_boolean? data, item - value - end - - def is_boolean?(data, item) - if item.class.respond_to? :columns_hash - column = item.class.columns_hash[data.to_s] and column.type == :boolean + html = format_attribute(resource, col.data) + # Don't add the same Arbre twice, while still allowing format_attribute to call status_tag + current_arbre_element << html unless current_arbre_element.children.include? html end end diff --git a/lib/active_admin/views/index_as_table.rb b/lib/active_admin/views/index_as_table.rb index 3eabc1ae2fb..0e32338b3b0 100644 --- a/lib/active_admin/views/index_as_table.rb +++ b/lib/active_admin/views/index_as_table.rb @@ -232,7 +232,7 @@ def table_for(*args, &block) def default_table proc do selectable_column - id_column if resource_class.primary_key # View based Models have no primary_key + id_column if resource_class.primary_key resource_class.content_columns.each do |col| column col.name.to_sym end @@ -266,7 +266,7 @@ def index_column(start_value = 1) # Display a column for the id def id_column - raise "#{resource_class.name} as no primary_key!" unless resource_class.primary_key + raise "#{resource_class.name} has no primary_key!" unless resource_class.primary_key column(resource_class.human_attribute_name(resource_class.primary_key), sortable: resource_class.primary_key) do |resource| if controller.action_methods.include?('show') link_to resource.id, resource_path(resource), class: "resource_id_link" diff --git a/spec/unit/auto_link_spec.rb b/spec/unit/auto_link_spec.rb index 822efc0b1eb..a6eb3b8181c 100644 --- a/spec/unit/auto_link_spec.rb +++ b/spec/unit/auto_link_spec.rb @@ -14,7 +14,7 @@ def admin_post_path(post) "/admin/posts/#{post.id}" end - def authorized?(_action, _subject) + def authorized?(*) true end diff --git a/spec/unit/view_helpers/display_helper_spec.rb b/spec/unit/view_helpers/display_helper_spec.rb new file mode 100644 index 00000000000..35305bbf792 --- /dev/null +++ b/spec/unit/view_helpers/display_helper_spec.rb @@ -0,0 +1,165 @@ +require 'rails_helper' + +describe ActiveAdmin::ViewHelpers::DisplayHelper do + include ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper + include ActiveAdmin::ViewHelpers::AutoLinkHelper + include ActiveAdmin::ViewHelpers::DisplayHelper + include MethodOrProcHelper + include ActionView::Helpers::UrlHelper + include ActionView::Helpers::TranslationHelper + + def active_admin_namespace + active_admin_application.namespaces[:admin] + end + + def authorized?(*) + true + end + + describe '#display_name' do + ActiveAdmin::Application.new.display_name_methods.map(&:to_s).each do |m| + it "should return #{m} when defined" do + klass = Class.new do + define_method(m) { m } + end + expect(display_name klass.new).to eq m + end + end + + it "should memoize the result for the class" do + subject = Class.new.new + expect(subject).to receive(:name).twice.and_return "My Name" + + expect(display_name subject).to eq "My Name" + + expect(ActiveAdmin.application).to_not receive(:display_name_methods) + expect(display_name subject).to eq "My Name" + end + + it "should not call a method if it's an association" do + klass = Class.new + subject = klass.new + allow(klass).to receive(:reflect_on_all_associations).and_return [ double(name: :login) ] + allow(subject).to receive :login + expect(subject).to_not receive :login + allow(subject).to receive(:email).and_return 'foo@bar.baz' + + expect(display_name subject).to eq 'foo@bar.baz' + end + + it "should return `nil` when the passed object is `nil`" do + expect(display_name nil).to eq nil + end + + it "should return 'false' when the passed object is `false`" do + expect(display_name false).to eq "false" + end + + it "should default to `to_s`" do + subject = Class.new.new + expect(display_name subject).to eq subject.to_s + end + + context "when no display name method is defined" do + context "on a Rails model" do + it "should show the model name" do + class ThisModel + extend ActiveModel::Naming + end + subject = ThisModel.new + expect(display_name subject).to eq "This model" + end + + it "should show the model name, plus the ID if in use" do + subject = Tagging.create! + expect(display_name subject).to eq "Tagging #1" + end + + it "should translate the model name" do + with_translation activerecord: {models: {tagging: {one: "Different"}}} do + subject = Tagging.create! + expect(display_name subject).to eq "Different #1" + end + end + end + end + end + + describe '#format_attribute' do + it 'calls the provided block to format the value' do + value = format_attribute double(foo: 2), ->r { r.foo + 1 } + + expect(value).to eq 3 + end + + it 'finds values as methods' do + value = format_attribute double(name: 'Joe'), :name + + expect(value).to eq 'Joe' + end + + it 'finds values from hashes' do + value = format_attribute({id: 100}, :id) + + expect(value).to eq '100' + end + + [1, 1.2, :a_symbol, Arbre::Element.new].each do |val| + it "calls to_s to format the value of type #{val.class}" do + value = format_attribute double(foo: val), :foo + + expect(value).to eq val.to_s + end + end + + it 'localizes dates' do + date = Date.parse '2016/02/28' + + value = format_attribute double(date: date), :date + + expect(value).to eq 'February 28, 2016' + end + + it 'localizes times' do + time = Time.parse '2016/02/28 9:34 PM' + + value = format_attribute double(time: time), :time + + expect(value).to eq 'February 28, 2016 21:34' + end + + it 'uses a display_name method for arbitrary objects' do + object = double to_s: :wrong, display_name: :right + + value = format_attribute double(object: object), :object + + expect(value).to eq :right + end + + it 'auto-links ActiveRecord records from foreign keys' do + post = Post.create! author: User.new + + value = format_attribute post, :author_id + + expect(value).to match / <\/a>/ + end + + it 'auto-links ActiveRecord records & uses a display_name method' do + post = Post.create! author: User.new(first_name: 'A', last_name: 'B') + + value = format_attribute post, :author + + expect(value).to match /A B<\/a>/ + end + + pending 'auto-links Mongoid records' + + it 'calls status_tag for boolean values' do + post = Post.new starred: true + + value = format_attribute post, :starred + + expect(value.to_s).to eq "Yes\n" + end + end +end diff --git a/spec/unit/view_helpers/display_name_spec.rb b/spec/unit/view_helpers/display_name_spec.rb deleted file mode 100644 index 21223c2d2a3..00000000000 --- a/spec/unit/view_helpers/display_name_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -require 'rails_helper' - -describe "display_name" do - - include ActiveAdmin::ViewHelpers - - ActiveAdmin::Application.new.display_name_methods.map(&:to_s).each do |m| - it "should return #{m} when defined" do - klass = Class.new do - define_method(m) { m } - end - expect(display_name klass.new).to eq m - end - end - - it "should memoize the result for the class" do - subject = Class.new.new - expect(subject).to receive(:name).twice.and_return "My Name" - expect(display_name subject).to eq "My Name" - expect(ActiveAdmin.application).to_not receive(:display_name_methods) - expect(display_name subject).to eq "My Name" - end - - it "should not call a method if it's an association" do - klass = Class.new - subject = klass.new - allow(klass).to receive(:reflect_on_all_associations).and_return [ double(name: :login) ] - allow(subject).to receive :login - expect(subject).to_not receive :login - allow(subject).to receive(:email).and_return 'foo@bar.baz' - expect(display_name subject).to eq 'foo@bar.baz' - end - - it "should return `nil` when the passed object is `nil`" do - expect(display_name nil).to eq nil - end - - it "should return 'false' when the passed objct is `false`" do - expect(display_name false).to eq "false" - end - - it "should default to `to_s`" do - subject = Class.new.new - expect(display_name subject).to eq subject.to_s - end - - context "when no display name method is defined" do - context "on a Rails model" do - it "should show the model name" do - class ThisModel - extend ActiveModel::Naming - end - subject = ThisModel.new - expect(display_name subject).to eq "This model" - end - - it "should show the model name, plus the ID if in use" do - subject = Tagging.create! - expect(display_name subject).to eq "Tagging #1" - end - - it "should translate the model name" do - with_translation activerecord: {models: {tagging: {one: "Different"}}} do - subject = Tagging.create! - expect(display_name subject).to eq "Different #1" - end - end - end - end - -end diff --git a/spec/unit/views/components/table_for_spec.rb b/spec/unit/views/components/table_for_spec.rb index 31710027063..d1cabfaf688 100644 --- a/spec/unit/views/components/table_for_spec.rb +++ b/spec/unit/views/components/table_for_spec.rb @@ -4,7 +4,11 @@ describe "creating with the dsl" do let(:collection) do - [Post.new(title: "First Post", starred: true), Post.new(title: "Second Post"), Post.new(title: "Third Post", starred: false)] + [ + Post.new(title: "First Post", starred: true), + Post.new(title: "Second Post"), + Post.new(title: "Third Post", starred: false) + ] end let(:assigns){ { collection: collection } } @@ -171,7 +175,8 @@ [ "First Post", "Second Post", - "Third Post" ].each_with_index do |content, index| + "Third Post" + ].each_with_index do |content, index| it "should create a cell with #{content}" do expect(table.find_by_tag("td")[index].content.strip).to eq content end @@ -197,24 +202,22 @@ end end - context "when creating many columns with symbols, blocks and strings" do let(:table) do render_arbre_component assigns, helpers do table_for(collection) do column "My Custom Title", :title - column :created_at , class:"datetime" + column :created_at, class: "datetime" end end end - - it "should add a class to each table header based on class option or the col name" do + it "should add a class to each header based on class option or the col name" do expect(table.find_by_tag("th").first.class_list.to_a.join(' ')).to eq "col col-my_custom_title" expect(table.find_by_tag("th").last.class_list.to_a.join(' ')).to eq "col datetime" end - it "should add a class to each cell based on class option or the col name" do + it "should add a class to each cell based on class option or the col name" do expect(table.find_by_tag("td").first.class_list.to_a.join(' ')).to eq "col col-my_custom_title" expect(table.find_by_tag("td").last.class_list.to_a.join(' ')).to eq "col datetime" end @@ -228,6 +231,7 @@ end end end + it "should render" do expect(table.find_by_tag("th").first.content).to eq "Title" end @@ -242,6 +246,7 @@ end end end + it "should render" do expect(table.find_by_tag("th")[0].content).to eq "Foo" expect(table.find_by_tag("th")[1].content).to eq "Bar" @@ -258,6 +263,7 @@ end end end + it "should render" do expect(table.find_by_tag("th")[0].content).to eq "Foo" expect(table.find_by_tag("td")[0].content).to eq "1" @@ -349,7 +355,6 @@ end describe "column sorting" do - def build_column(*args, &block) ActiveAdmin::Views::TableFor::Column.new(*args, &block) end From 98cadbaf052218eb3d555eaa99242d4c73edfb61 Mon Sep 17 00:00:00 2001 From: KUROKI Shinsuke Date: Sat, 26 Mar 2016 21:28:55 +0900 Subject: [PATCH 0106/3836] Modify SearchMethodSelect help comment to follow actual condition --- .../inputs/filters/base/search_method_select.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/active_admin/inputs/filters/base/search_method_select.rb b/lib/active_admin/inputs/filters/base/search_method_select.rb index 0c2f8adf114..45cfb09ca3c 100644 --- a/lib/active_admin/inputs/filters/base/search_method_select.rb +++ b/lib/active_admin/inputs/filters/base/search_method_select.rb @@ -4,9 +4,9 @@ # Your class must declare available filters for this module to work. # Those filters must be recognizable by Ransack. For example: # -# class FilterNumericInput < ::Formtastic::Inputs::NumberInput -# include FilterBase -# include FilterBase::SearchMethodSelect +# class NumericInput < ::Formtastic::Inputs::NumberInput +# include Base +# include Base::SearchMethodSelect # # filter :equals, :greater_than, :less_than # end From 1aee48e63702fc0e52a088788ada8299c4a005ea Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 26 Mar 2016 14:16:21 -0500 Subject: [PATCH 0107/3836] Don't create cucumber Rails environments This simplifies our test setup, making it easier to understand. The previous version created a cucumber and cucumber_with_reloading Rails environment, but I removed that in favor of setting a custom environment variable. --- cucumber.yml | 2 +- features/support/env.rb | 5 ++- spec/support/rails_template.rb | 45 ++----------------- spec/support/templates/cucumber.rb | 24 ---------- .../templates/cucumber_with_reloading.rb | 5 --- 5 files changed, 7 insertions(+), 74 deletions(-) delete mode 100644 spec/support/templates/cucumber.rb delete mode 100644 spec/support/templates/cucumber_with_reloading.rb diff --git a/cucumber.yml b/cucumber.yml index 2b8ee256bd4..4fdbfaac3ce 100644 --- a/cucumber.yml +++ b/cucumber.yml @@ -1,3 +1,3 @@ default: --format 'progress' --require features/support/env.rb --require features/step_definitions features --tags ~@requires-reloading --tags ~@wip wip: --format 'progress' --require features/support/env.rb --require features/step_definitions features --tags @wip:3 --wip features -class-reloading: RAILS_ENV=cucumber_with_reloading --format 'progress' --require features/support/env.rb --require features/step_definitions features --tags @requires-reloading +class-reloading: CLASS_RELOADING=true --format 'progress' --require features/support/env.rb --require features/step_definitions features --tags @requires-reloading diff --git a/features/support/env.rb b/features/support/env.rb index fefcd2691ed..8d490a059ad 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -4,7 +4,7 @@ # instead of editing this one. Cucumber will automatically load all features/**/*.rb # files. -ENV["RAILS_ENV"] ||= "cucumber" +ENV['RAILS_ENV'] = 'test' require File.expand_path('../../../spec/spec_helper', __FILE__) @@ -94,7 +94,8 @@ require 'database_cleaner' require 'database_cleaner/cucumber' DatabaseCleaner.strategy = :truncation - rescue LoadError => ignore_if_database_cleaner_not_present + rescue LoadError + # ignore if database_cleaner isn't present end end diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index bf7f3a55a9b..07a69738326 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -1,18 +1,5 @@ # Rails template to build the sample app for specs -# Create a cucumber database and environment -copy_file File.expand_path('../templates/cucumber.rb', __FILE__), 'config/environments/cucumber.rb' -copy_file File.expand_path('../templates/cucumber_with_reloading.rb', __FILE__), 'config/environments/cucumber_with_reloading.rb' - -gsub_file 'config/database.yml', /^test:.*\n/, "test: &test\n" -gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *test\n database: db/cucumber.sqlite3" -gsub_file 'config/database.yml', /\z/, "\ncucumber_with_reloading:\n <<: *test\n database: db/cucumber.sqlite3" - -if File.exists? 'config/secrets.yml' - gsub_file 'config/secrets.yml', /\z/, "\ncucumber:\n secret_key_base: #{'o' * 128}" - gsub_file 'config/secrets.yml', /\z/, "\ncucumber_with_reloading:\n secret_key_base: #{'o' * 128}" -end - generate :model, 'post title:string body:text published_at:datetime author_id:integer ' + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' create_file 'app/models/post.rb', <<-RUBY.strip_heredoc, force: true @@ -118,8 +105,9 @@ class Tagging < ActiveRecord::Base end RUBY -inject_into_file 'config/environments/test.rb', <<-RUBY, after: 'config.cache_classes = true' +gsub_file 'config/environments/test.rb', / config.cache_classes = true/, <<-RUBY + config.cache_classes = !ENV['CLASS_RELOADING'] config.action_mailer.default_url_options = {host: 'example.com'} config.assets.digest = false @@ -163,35 +151,8 @@ class Tagging < ActiveRecord::Base # https://github.com/plataformatec/devise/issues/2554 gsub_file 'config/initializers/devise.rb', /# config.secret_key =/, 'config.secret_key =' -rake 'db:migrate db:test:prepare' -run '/usr/bin/env RAILS_ENV=cucumber rake db:migrate' +rake 'db:migrate' if ENV['INSTALL_PARALLEL'] inject_into_file 'config/database.yml', "<%= ENV['TEST_ENV_NUMBER'] %>", after: 'test.sqlite3' - inject_into_file 'config/database.yml', "<%= ENV['TEST_ENV_NUMBER'] %>", after: 'cucumber.sqlite3', force: true - - # Note: this is hack! - # Somehow, calling parallel_tests tasks from Rails generator using Thor does not work ... - # RAILS_ENV variable never makes it to parallel_tests tasks. - # We need to call these tasks in the after set up hook in order to create cucumber DBs + run migrations on test & cucumber DBs - create_file 'lib/tasks/parallel.rake', <<-RUBY.strip_heredoc - namespace :parallel do - def run_in_parallel(cmd, options) - count = "-n #{options[:count]}" if options[:count] - executable = 'parallel_test' - command = "#{executable} --exec '#{cmd}' #{count} #{'--non-parallel' if options[:non_parallel]}" - abort unless system(command) - end - - desc "create cucumber databases via db:create --> parallel:create_cucumber_db[num_cpus]" - task :create_cucumber_db, :count do |t, args| - run_in_parallel("rake db:create RAILS_ENV=cucumber", args) - end - - desc "load dumped schema for cucumber databases" - task :load_schema_cucumber_db, :count do |t,args| - run_in_parallel("rake db:schema:load RAILS_ENV=cucumber", args) - end - end - RUBY end diff --git a/spec/support/templates/cucumber.rb b/spec/support/templates/cucumber.rb deleted file mode 100644 index 183fa0f8cc9..00000000000 --- a/spec/support/templates/cucumber.rb +++ /dev/null @@ -1,24 +0,0 @@ -require File.expand_path('config/environments/test', Rails.root) - -# rails/railties/lib/rails/test_help.rb aborts if the environment is not 'test'. (Rails 3.0.0.beta3) -# We can't run Cucumber/RSpec/Test_Unit tests in different environments then. -# -# For now, I patch StringInquirer so that Rails.env.test? returns true when Rails.env is 'test' or 'cucumber' -# -# https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4458-rails-should-allow-test-to-run-in-cucumber-environment -module ActiveSupport - class StringInquirer < String - def method_missing(method_name, *arguments) - if method_name.to_s[-1,1] == "?" - test_string = method_name.to_s[0..-2] - if test_string == 'test' - self == 'test' or self == 'cucumber' - else - self == test_string - end - else - super - end - end - end -end diff --git a/spec/support/templates/cucumber_with_reloading.rb b/spec/support/templates/cucumber_with_reloading.rb deleted file mode 100644 index e9b2592901a..00000000000 --- a/spec/support/templates/cucumber_with_reloading.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.expand_path('config/environments/cucumber', Rails.root) - -Rails.application.class.configure do - config.cache_classes = false -end From 3a4785a5776436413a7515b243ebbea4cb8cc65d Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sat, 26 Mar 2016 15:21:11 -0500 Subject: [PATCH 0108/3836] version-constrain the mime-types gem Travis is getting this error with Rails 4.2 on Ruby 1.9: >Gem::InstallError: mime-types-data requires Ruby version >= 2.0. I wish Bundler could automatically find an older version instead of us having to specify it... --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index e5a426841a6..bbef0e24795 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,8 @@ if rails_version == '> 5.x' gem 'activerecord-jdbc-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: :jruby end +gem 'mime-types', '< 3' # Remove this line when we drop support for Ruby 1.9 + # Optional dependencies gem 'cancan' gem 'devise', rails_version == '> 5.x' ? '> 4.x' : '~> 3.5' From 988b34e77d1f69efa5fef97e0397b64b8656d11d Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Mon, 28 Mar 2016 14:07:14 +0200 Subject: [PATCH 0109/3836] allow failures for all rails 5.x versions --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6745e0783b1..d63ad735305 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,8 @@ matrix: - rvm: 1.9 env: RAILS="> 5.x" allow_failures: + - rvm: 2.3.0 + env: RAILS="> 5.x" - rvm: jruby-9.0.4.0 env: RAILS="> 5.x" branches: From 1ea2a7de6ae3ccd02fbc86450de39c9d181eb23d Mon Sep 17 00:00:00 2001 From: Roger Kind Kristiansen Date: Thu, 31 Mar 2016 10:39:42 +0200 Subject: [PATCH 0110/3836] Change Norwegian login title to improve text flow Previous title text looked really strange in the context it was being used (combined with the site title in the login window). This makes it look more fluent in Norwegian. --- config/locales/nb.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/nb.yml b/config/locales/nb.yml index e21370ba8d3..aa3a00d1138 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -88,7 +88,7 @@ nb: title: "Opprett brukerkonto" submit: "Opprett" login: - title: "Logg inn" + title: "Innlogging" remember_me: "Husk meg" submit: "Logg inn" reset_password: From 2a6c323f26f5212c22225bfb1e8f935c15ac5f2a Mon Sep 17 00:00:00 2001 From: Roger Kind Kristiansen Date: Thu, 31 Mar 2016 10:46:35 +0200 Subject: [PATCH 0111/3836] Add Norwegian search_status translations These entries were completely missing from the nb.yml translation file. --- config/locales/nb.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/locales/nb.yml b/config/locales/nb.yml index aa3a00d1138..fb80d694e94 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -31,6 +31,11 @@ nb: ends_with: "Slutter med" greater_than: "Større enn" less_than: "Mindre enn" + search_status: + headline: "Søkestatus:" + current_scope: "Søkeområde:" + current_filters: "Gjeldende filtre:" + no_current_filters: "Ingen" status_tag: "yes": "Ja" "no": "Nei" From c7e284cfdac82d9d81c7e5ea596f5bd115e0754a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C3=96zg=C3=BCr?= Date: Thu, 31 Mar 2016 18:00:25 +0300 Subject: [PATCH 0112/3836] Improve Turkish translations Devise translations are mostly copied from devise-i18n. --- config/locales/tr.yml | 127 +++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 44 deletions(-) diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 6f0070b43f5..bc79381acf9 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1,97 +1,136 @@ tr: active_admin: - dashboard: "Kontrol Paneli" + dashboard: "Gösterge Paneli" dashboard_welcome: - welcome: "Active Admin'e Hoşgeldiniz. Burası öntanımlı Kontrol Paneli sayfasıdır." - call_to_action: "Kontrol Paneline bölümler eklemek için 'app/admin/dashboard.rb' dosyasına bakabilirsin." + welcome: "Active Admin'e hoş geldiniz. Burası varsayılan gösterge paneli sayfasıdır." + call_to_action: "Buraya bölümler eklemek için 'app/admin/dashboard.rb' dosyasına bakabilirsiniz." view: "Görüntüle" - edit: "Değiştir" + edit: "Düzenle" delete: "Sil" - delete_confirmation: "Bu kaydı silmek istediğine emin misin?" + delete_confirmation: "Bu kaydı silmek istediğinizden emin misiniz?" new_model: "Yeni %{model}" - edit_model: "%{model} modelini düzenle" - delete_model: "%{model} modelini sil" - details: "%{model} ayrıntıları" + edit_model: "%{model} Kaydını Düzenle" + delete_model: "%{model} Kaydını Sil" + details: "%{model} Ayrıntıları" cancel: "İptal" empty: "Boş" previous: "Önceki" next: "Sonraki" download: "İndir:" - has_many_new: "Yeni %{model} kaydı ekle" + has_many_new: "Yeni %{model} Ekle" has_many_delete: "Sil" - has_many_remove: "Çıkarmak" + has_many_remove: "Çıkar" filters: buttons: filter: "Filtrele" clear: "Filtreleri Temizle" predicates: - contains: "içerir" + contains: "İçerir" equals: "Eşittir" - starts_with: "ile başlar" - ends_with: "ile biter" - greater_than: "Büyükse" - less_than: "Küçükse" + starts_with: "İle başlar" + ends_with: "İle biter" + greater_than: "Büyüktür" + less_than: "Küçüktür" + search_status: + headline: "Arama" + current_scope: "Kapsam:" + current_filters: "Seçili filtreler:" + no_current_filters: "Yok" status_tag: "yes": "Evet" "no": "Hayır" main_content: "İçeriği görüntülemek için lütfen %{model}#main_content metodunu ekleyin." - logout: "Oturumu Sonlandır" - powered_by: "Powered by %{active_admin} %{version}" + logout: "Çıkış Yap" + powered_by: "%{active_admin} %{version} tarafından desteklenmektedir." sidebars: filters: "Filtreler" + search_status: "Arama Durumu" pagination: - empty: "%{model} boş" - one: "1 %{model} kaydı görüntüleniyor" - one_page: "%{n} kayıt %{model} modelinde görüntüleniyor" - multiple: "%{model} toplam %{total} kayıt bulundu. %{from} ile %{to} arası arası görüntüleniyor" - multiple_without_total: "%{model}. %{from} ile %{to} arası arası görüntüleniyor" + empty: "Hiç %{model} yok" + one: "1 %{model} görüntüleniyor" + one_page: "%{n} %{model} kaydının tamamı görüntüleniyor" + multiple: "%{from} - %{to} arası %{model} görüntüleniyor (toplam %{total} kayıt)" + multiple_without_total: "%{from} - %{to} arası %{model} görüntüleniyor" entry: - one: "Girdi" - other: "Girdiler" - any: "Herhangi" + one: "kayıt" + other: "kayıtlar" + any: "Herhangi biri" blank_slate: - content: "Herhangi bir %{resource_name} kaydı bulunamadı" + content: "Henüz %{resource_name} yok." link: "Bir tane oluşturun" dropdown_actions: - button_label: "Işlemler" + button_label: "İşlemler" batch_actions: - button_label: "Toplu işlemler" - default_confirmation: "Bunu yapmak istediğinden emin misin?" - delete_confirmation: "%{plural_model} kayıtlarını silmek istediğinize emin misiniz?" + button_label: "Toplu İşlemler" + default_confirmation: "Bunu yapmak istediğinizden emin misiniz?" + delete_confirmation: "Bu %{plural_model} kayıtlarını silmek istediğinizden emin misiniz?" succesfully_destroyed: - one: "1 %{model} kaydı başarıyla silindi." - other: "Toplam %{count} kayıt %{plural_model} modelinden silindi" - selection_toggle_explanation: "Seçimi Değiştir" - link: "Ekle" - action_label: "%{title} Seçildi" + one: "1 %{model} başarıyla silindi" + other: "Toplam %{count} %{plural_model} başarıyla silindi" + selection_toggle_explanation: "(Seçimi Değiştir)" + link: "Yeni oluştur" + action_label: "Seçilenleri %{title}" labels: destroy: "Sil" comments: + created_at: "Oluşturma Tarihi" + resource_type: "Kayıt Tipi" + author_type: "Yazar Tipi" body: "Ayrıntı" author: "Yazar" title: "Yorum" add: "Yorum Ekle" - resource: "Kaynak" - no_comments_yet: "Henüz Yorum Yok" + delete: "Yorumu Sil" + delete_confirmation: "Bu yorumları silmek istediğinizden emin misiniz?" + resource: "Kayıt" + no_comments_yet: "Henüz yorum yok." + author_missing: "Anonim" title_content: "Yorumlar (%{count})" errors: empty_text: "Yorum boş olarak kaydedilemez." devise: + username: + title: "Kullanıcı adı" + email: + title: "E-posta adresi" + subdomain: + title: "Alt alan adı" + password: + title: "Şifre" + sign_up: + title: "Kaydol" + submit: "Kaydol" login: - title: "Oturum aç" - remember_me: "Beni Hatırla" - submit: "Gönder" + title: "Giriş yap" + remember_me: "Beni hatırla" + submit: "Giriş yap" reset_password: - title: "Şifreni mi unuttun?" + title: "Şifrenizi mi unuttunuz?" submit: "Şifremi sıfırla" change_password: title: "Şifrenizi değiştirin" submit: "Şifremi değiştir" + unlock: + title: "Hesap geri açma talimatlarını tekrar gönder" + submit: "Hesap geri açma talimatlarını tekrar gönder" resend_confirmation_instructions: title: "Onaylama talimatlarını tekrar gönder" submit: "Onaylama talimatlarını tekrar gönder" links: - sign_in: "Oturum aç" - forgot_your_password: "Şifreni mi unuttun?" + sign_up: "Kaydol" + sign_in: "Giriş yap" + forgot_your_password: "Şifrenizi mi unuttunuz?" sign_in_with_omniauth_provider: "%{provider} ile giriş yapın" - + resend_unlock_instructions: "Hesap geri açma talimatlarını tekrar gönder" + resend_confirmation_instructions: "Onaylama talimatlarını tekrar gönder" + unsupported_browser: + headline: "ActiveAdmin Internet Explorer 8 ve altı artık desteklememektedir." + recommendation: "Son sürüm Internet Explorer, Google Chrome, ya da Firefox tarayıcılarından birine geçmenizi tavsiye ederiz." + turn_off_compatibility_view: "IE 9 ya da üstünü kullanıyorsanız, \"Uyumluluk Görünümü\"nü kapatmayı unutmayın." + access_denied: + message: "Bu işlemi gerçekleştirmek için yetkiniz yok." + index_list: + table: "Tablo" + block: "Liste" + grid: "Izgara" + blog: "Blog" From 6c504265fb352e580b056e35fe57273d30730841 Mon Sep 17 00:00:00 2001 From: Christopher Styles Date: Wed, 6 Apr 2016 09:18:47 -0700 Subject: [PATCH 0113/3836] Fix typo in simple columns section --- docs/12-arbre-components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/12-arbre-components.md b/docs/12-arbre-components.md index 7c411f20c9c..e32021ef618 100644 --- a/docs/12-arbre-components.md +++ b/docs/12-arbre-components.md @@ -56,7 +56,7 @@ the rest. #### Simple Columns -To create simple columnns, use the `columns` method. Within the block, call +To create simple columns, use the `columns` method. Within the block, call the #column method to create a new column. ```ruby From 6d9a3a3b2a8ad9fc335030c14a04e3b1cdff4492 Mon Sep 17 00:00:00 2001 From: Logan Serman Date: Thu, 28 Apr 2016 12:00:33 -0500 Subject: [PATCH 0114/3836] Fix typo on authorization_adapter.rb documentation --- lib/active_admin/authorization_adapter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/authorization_adapter.rb b/lib/active_admin/authorization_adapter.rb index d9e181acd0d..f283672172e 100644 --- a/lib/active_admin/authorization_adapter.rb +++ b/lib/active_admin/authorization_adapter.rb @@ -47,7 +47,7 @@ def initialize(resource, user) # the class of the subject also. For example, Active Admin uses the class # of the resource to decide if the resource should be displayed in the # global navigation. To deal with this nicely in a case statement, take - # a look at `#normalized(klasss)` + # a look at `#normalized(klass)` # # @return [Boolean] def authorized?(action, subject = nil) From cba63ec3088b343334a5afb5d079a01106be69a6 Mon Sep 17 00:00:00 2001 From: Michael Zelenyuk Date: Thu, 28 Apr 2016 16:48:20 +0300 Subject: [PATCH 0115/3836] Fix Ukrainian translation --- config/locales/uk.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 37fc9fa24f6..5933262c0f9 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -2,8 +2,8 @@ uk: active_admin: dashboard: "Панель керування" dashboard_welcome: - welcome: "Ласкаво просимо в Active Admin. Це стандартна сторінка керування сайтом." - call_to_action: "Щоб додати сюди що-небудь загляніть в 'app/admin/dashboard.rb'" + welcome: "Ласкаво просимо до Active Admin. Це стандартна сторінка керування сайтом." + call_to_action: "Щоб додати сюди що-небудь, зазирніть у 'app/admin/dashboard.rb'" view: "Переглянути" edit: "Змінити" delete: "Видалити" @@ -12,7 +12,7 @@ uk: edit_model: "Змінити %{model}" delete_model: "Видалити %{model}" details: "%{model} детальніше" - cancel: "Відміна" + cancel: "Скасувати" empty: "Пусто" previous: "Поперед." next: "Наст." @@ -30,7 +30,7 @@ uk: starts_with: "Починається з" ends_with: "Закінчується" greater_than: "більше" - less_than: "меньше" + less_than: "менше" search_status: headline: "Статус пошуку:" current_scope: "Область:" @@ -58,7 +58,7 @@ uk: other: "записів" any: "Будь-який" blank_slate: - content: "Покищо немає %{resource_name}." + content: "Поки-що немає %{resource_name}." link: "Створити" dropdown_actions: button_label: "Oперації" @@ -71,7 +71,7 @@ uk: few: "Успішно видалено: %{count} %{plural_model}" many: "Успішно видалено: %{count} %{plural_model}" other: "Успішно видалено: %{count} %{plural_model}" - selection_toggle_explanation: "(Відмінити все / Зняти виділення)" + selection_toggle_explanation: "(Скасувати все / Зняти виділення)" link: "Створити" action_label: "%{title} вибране" labels: @@ -84,7 +84,7 @@ uk: title: "Коментар" add: "Додати Коментар" resource: "Ресурс" - no_comments_yet: "Покищо немає коментарів." + no_comments_yet: "Поки-що немає коментарів." author_missing: "Анонім" title_content: "Коментарі (%{count})" errors: @@ -93,7 +93,7 @@ uk: username: title: "Ім'я користувача" email: - title: "Ел. пошта" + title: "Електронна пошта" subdomain: title: "Піддомен" password: @@ -115,8 +115,8 @@ uk: title: "Відправити повторно інструкції з розблокування" submit: "Відправити повторно інструкції з розблокування" resend_confirmation_instructions: - title: "Вислати повторно листа з активацією" - submit: "Вислати повторно листа з активацією" + title: "Відправити повторно листа з активацією" + submit: "Відправити повторно листа з активацією" links: sign_up: "Зареєструватись" sign_in: "Увійти" @@ -127,7 +127,7 @@ uk: unsupported_browser: headline: "Зверніть, будь-ласка, увагу, що ActiveAdmin більше не підтримує Internet Explorer 8 версії і нижче" recommendation: "Ми рекомендуємо оновити версію вашого браузеру (Internet Explorer, Google Chrome, або Firefox)." - turn_off_compatibility_view: "Якщо ви використовуєте IE 9 і вище переконайтесь, що ви виключили опцію \"Перегляд в режимі сумісності\"." + turn_off_compatibility_view: "Якщо ви використовуєте IE 9 і вище, переконайтесь, що ви вимкнули опцію \"Перегляд в режимі сумісності\"." access_denied: message: "Ви не авторизовані для виконання даної дії." index_list: From a929d335cfd6c1071b2ed437ae68f4e43fbd142b Mon Sep 17 00:00:00 2001 From: Alfredo Date: Sat, 7 May 2016 02:08:18 -0500 Subject: [PATCH 0116/3836] capitalizes strings in spanish locales for iniciar sesion and register --- config/locales/es-MX.yml | 6 +++--- config/locales/es.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index f034caba4f3..b52bf9c6383 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -74,9 +74,9 @@ es-MX: empty_text: "El comentario no fue guardado, el texto estaba vacío." devise: login: - title: "iniciar sesión" + title: "Iniciar Sesión" remember_me: "Recordarme" - submit: "iniciar sesión" + submit: "Iniciar Sesión" reset_password: title: "¿Olvidó su contraseña?" submit: "Restablecer mi contraseña" @@ -84,7 +84,7 @@ es-MX: title: "Cambie su contraseña" submit: "Cambiar mi contraseña" links: - sign_in: "registrarse" + sign_in: "Registrarse" forgot_your_password: "¿Olvidó su contraseña?" sign_in_with_omniauth_provider: "Conéctate con %{provider}" index_list: diff --git a/config/locales/es.yml b/config/locales/es.yml index 10c58bb0769..0d9155ff2d8 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -101,9 +101,9 @@ es: title: "Registrarse" submit: "Registrarse" login: - title: "iniciar sesión" + title: "Iniciar Sesión" remember_me: "Recordarme" - submit: "iniciar sesión" + submit: "Iniciar Sesión" reset_password: title: "¿Olvidó su contraseña?" submit: "Restablecer mi contraseña" @@ -118,7 +118,7 @@ es: submit: "Reenviar instrucciones de confirmación" links: sign_up: "Ingresar" - sign_in: "registrarse" + sign_in: "Registrarse" forgot_your_password: "¿Olvidó su contraseña?" sign_in_with_omniauth_provider: "Conéctate con %{provider}" resend_unlock_instructions: "Reenviar instrucciones de desbloqueo" From 3c9c0b6bc77936d2ca4fd122e7975569b94bfa6b Mon Sep 17 00:00:00 2001 From: arr-dev Date: Thu, 12 May 2016 13:43:13 +0200 Subject: [PATCH 0117/3836] Site title image alt from proc --- lib/active_admin/views/components/site_title.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/views/components/site_title.rb b/lib/active_admin/views/components/site_title.rb index 3621314d550..9125765d4ba 100644 --- a/lib/active_admin/views/components/site_title.rb +++ b/lib/active_admin/views/components/site_title.rb @@ -46,7 +46,7 @@ def title_text def title_image path = helpers.render_or_call_method_or_proc_on(self, @namespace.site_title_image) - helpers.image_tag(path, id: "site_title_image", alt: @namespace.site_title) + helpers.image_tag(path, id: "site_title_image", alt: title_text) end end From 5330ab0a1bef91aa772619198d8e983337b6bf4c Mon Sep 17 00:00:00 2001 From: Ralin Chimev Date: Thu, 19 May 2016 20:24:08 +0300 Subject: [PATCH 0118/3836] Fix select input name concatenation Do not modify the source string when appending '_in' or '_eq' to searchable_method_name otherwise it gets appended at each call. Example: `payment_type_code_eq_eq_eq_eq_eq_eq_eq_eq_eq_eq` Fixes #4121. --- lib/active_admin/inputs/filters/select_input.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/inputs/filters/select_input.rb b/lib/active_admin/inputs/filters/select_input.rb index d9187e29094..ceda463c631 100644 --- a/lib/active_admin/inputs/filters/select_input.rb +++ b/lib/active_admin/inputs/filters/select_input.rb @@ -7,7 +7,7 @@ class SelectInput < ::Formtastic::Inputs::SelectInput def input_name return method if seems_searchable? - searchable_method_name.concat multiple? ? '_in' : '_eq' + searchable_method_name + (multiple? ? '_in' : '_eq') end def searchable_method_name From 39ee0810ace796a0688431f52b649e88eb3eb8c0 Mon Sep 17 00:00:00 2001 From: Diego Silva Date: Wed, 25 May 2016 23:06:20 -0300 Subject: [PATCH 0119/3836] Missing pt-BR translations for comments * created_at * delete * delete_confirmation --- config/locales/pt-BR.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 6988e398ef8..3585db1b2bb 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -73,12 +73,15 @@ pt-BR: labels: destroy: "Excluir" comments: + created_at: "Criado em" resource_type: "Tipo de Objeto" author_type: "Tipo de Autor" body: "Conteúdo" author: "Autor" title: "Comentário" add: "Adicionar Comentário" + delete: "Deletar comentário" + delete_confirmation: "Tem certeza que deseja excluir este comentário?" resource: "Objeto" no_comments_yet: "Nenhum comentário." author_missing: "Anônimo" From 431af3b0b937e1e79699e7b595fd0cecbe7b0dca Mon Sep 17 00:00:00 2001 From: reubenbrown Date: Thu, 2 Jun 2016 00:01:42 -0500 Subject: [PATCH 0120/3836] Update 14-gotchas.md Fixed grammatical error in the css section and fixed spelling of "commands" --- docs/14-gotchas.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 84f1ce4b40c..d0f7fd162d2 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -59,9 +59,9 @@ end ## CSS -In order to avoid the override of your application style with the Active Admin one, you can do one of this things: +In order to avoid the override of your application style with the Active Admin one, you can do one of these things: * You can properly move the generated file `active_admin.scss` from `app/assets/stylesheets` to `vendor/assets/stylesheets`. -* You can remove all `require_tree` comands from your root level css files, where the `active_admin.scss` is in the tree. +* You can remove all `require_tree` commands from your root level css files, where the `active_admin.scss` is in the tree. ## Conflicts From 2c6c872c96e79d7192ef0054399fc007c50afebf Mon Sep 17 00:00:00 2001 From: Benjamin Bristow Date: Thu, 2 Jun 2016 16:25:51 +0100 Subject: [PATCH 0121/3836] Deprecation warning fix for Kaminari --- lib/active_admin/resource_controller/decorators.rb | 2 +- lib/active_admin/views/components/paginated_collection.rb | 6 +++--- spec/unit/views/components/paginated_collection_spec.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/active_admin/resource_controller/decorators.rb b/lib/active_admin/resource_controller/decorators.rb index c0c02a1ad5b..6015089d565 100644 --- a/lib/active_admin/resource_controller/decorators.rb +++ b/lib/active_admin/resource_controller/decorators.rb @@ -67,7 +67,7 @@ def self.wrap(decorator) def self.wrap!(parent, name) ::Class.new parent do delegate :reorder, :page, :current_page, :total_pages, :limit_value, - :total_count, :num_pages, :to_key, :group_values, :except, + :total_count, :total_pages, :to_key, :group_values, :except, :find_each, :ransack define_singleton_method(:name) { name } diff --git a/lib/active_admin/views/components/paginated_collection.rb b/lib/active_admin/views/components/paginated_collection.rb index bede97dbc81..b7f66d7ff3a 100644 --- a/lib/active_admin/views/components/paginated_collection.rb +++ b/lib/active_admin/views/components/paginated_collection.rb @@ -44,7 +44,7 @@ def build(collection, options = {}) @display_total = options.delete(:pagination_total) { true } @per_page = options.delete(:per_page) - unless collection.respond_to?(:num_pages) + unless collection.respond_to?(:total_pages) raise(StandardError, "Collection is not a paginated scope. Set collection.page(params[:page]).per(10) before calling :paginated_collection.") end @@ -132,7 +132,7 @@ def page_entries_info(options = {}) end if @display_total - if collection.num_pages < 2 + if collection.total_pages < 2 case collection_size when 0; I18n.t("active_admin.pagination.empty", model: entries_name) when 1; I18n.t("active_admin.pagination.one", model: entry_name) @@ -149,7 +149,7 @@ def page_entries_info(options = {}) end else # Do not display total count, in order to prevent a `SELECT count(*)`. - # To do so we must not call `collection.num_pages` + # To do so we must not call `collection.total_pages` offset = (collection.current_page - 1) * collection.limit_value I18n.t "active_admin.pagination.multiple_without_total", model: entries_name, diff --git a/spec/unit/views/components/paginated_collection_spec.rb b/spec/unit/views/components/paginated_collection_spec.rb index f4f0804618f..1a678e635d7 100644 --- a/spec/unit/views/components/paginated_collection_spec.rb +++ b/spec/unit/views/components/paginated_collection_spec.rb @@ -212,7 +212,7 @@ def paginated_collection(*args) describe "set to false" do it "should not show the total item counts" do - expect(collection).not_to receive(:num_pages) + expect(collection).not_to receive(:total_pages) expect(collection).not_to receive(:total_pages) pagination = paginated_collection(collection, pagination_total: false) info = pagination.find_by_class('pagination_information').first.content.gsub(' ',' ') From 6aeb73779b68ee2bdf24571c76461087f1b33b21 Mon Sep 17 00:00:00 2001 From: Gaurav Sharma Date: Sat, 4 Jun 2016 15:30:28 +0530 Subject: [PATCH 0122/3836] fix typo in forms and show pages documentation --- docs/5-forms.md | 2 +- docs/6-show-pages.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/5-forms.md b/docs/5-forms.md index 7f999996f7f..c16bc1aa7df 100644 --- a/docs/5-forms.md +++ b/docs/5-forms.md @@ -147,7 +147,7 @@ This is particularly useful to display errors on virtual or hidden attributes. # Tabs -You can arrage content in tabs as shown below: +You can arrange content in tabs as shown below: ```ruby form do |f| diff --git a/docs/6-show-pages.md b/docs/6-show-pages.md index 0f9c421ea87..b81c8033022 100644 --- a/docs/6-show-pages.md +++ b/docs/6-show-pages.md @@ -78,7 +78,7 @@ end # Tabs -You can arrage content in tabs as shown below: +You can arrange content in tabs as shown below: ```ruby ActiveAdmin.register Order do From aeb0e158608d04ce33ed8dfc1a1d7b4073b20dca Mon Sep 17 00:00:00 2001 From: Hugo Duksis Date: Thu, 16 Jun 2016 19:56:30 +0300 Subject: [PATCH 0123/3836] force usage of jQuery 2 from jquery-rails --- app/assets/javascripts/active_admin/base.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/active_admin/base.js.coffee b/app/assets/javascripts/active_admin/base.js.coffee index 6f184cafcc5..ea5cfa82241 100644 --- a/app/assets/javascripts/active_admin/base.js.coffee +++ b/app/assets/javascripts/active_admin/base.js.coffee @@ -1,4 +1,4 @@ -#= require jquery +#= require jquery2 #= require ./jquery_ui #= require jquery_ujs #= require_self From 37f30bc5a01d40eb9c56ab71a66d4a0ef94e2c54 Mon Sep 17 00:00:00 2001 From: Fred Leitz Date: Sat, 18 Jun 2016 20:16:58 -0700 Subject: [PATCH 0124/3836] add support for turbolinks 5 --- .../active_admin/initializers/batch_actions.js.coffee | 2 +- .../javascripts/active_admin/initializers/datepicker.js.coffee | 2 +- .../javascripts/active_admin/initializers/filters.js.coffee | 2 +- app/assets/javascripts/active_admin/initializers/tabs.js.coffee | 2 +- app/assets/javascripts/active_admin/lib/batch_actions.js.coffee | 2 +- app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee b/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee index acda259a692..fe4a04633be 100644 --- a/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee @@ -1,4 +1,4 @@ -$(document).on 'ready page:load', -> +$(document).on 'ready page:load turbolinks:load', -> # In order for index scopes to overflow properly onto the next line, we have # to manually set its width based on the width of the batch action button. if (batch_actions_selector = $('.table_tools .batch_actions_selector')).length diff --git a/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee b/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee index ef69d98e953..fcbd4dc6916 100644 --- a/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee @@ -1,4 +1,4 @@ -$(document).on 'ready page:load', -> +$(document).on 'ready page:load turbolinks:load', -> $(document).on 'focus', 'input.datepicker:not(.hasDatepicker)', -> input = $(@) diff --git a/app/assets/javascripts/active_admin/initializers/filters.js.coffee b/app/assets/javascripts/active_admin/initializers/filters.js.coffee index 992da9d46e6..6465f9d0abd 100644 --- a/app/assets/javascripts/active_admin/initializers/filters.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/filters.js.coffee @@ -1,4 +1,4 @@ -$(document).on 'ready page:load', -> +$(document).on 'ready page:load turbolinks:load', -> # Clear Filters button $('.clear_filters_btn').click -> params = window.location.search.slice(1).split('&') diff --git a/app/assets/javascripts/active_admin/initializers/tabs.js.coffee b/app/assets/javascripts/active_admin/initializers/tabs.js.coffee index b469cca3d69..33a5dc5cf6e 100644 --- a/app/assets/javascripts/active_admin/initializers/tabs.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/tabs.js.coffee @@ -1,3 +1,3 @@ -$(document).on 'ready page:load', -> +$(document).on 'ready page:load turbolinks:load', -> # Tab navigation $('#active_admin_content .tabs').tabs() diff --git a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee index 42013a07874..1a9f787b7bf 100644 --- a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee +++ b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee @@ -1,4 +1,4 @@ -$(document).on 'ready page:load', -> +$(document).on 'ready page:load turbolinks:load', -> # # Use ActiveAdmin.modal_dialog to prompt user if confirmation is required for current Batch Action diff --git a/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee b/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee index 446beb2debd..bdb7b7c0233 100644 --- a/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee +++ b/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee @@ -97,5 +97,5 @@ class ActiveAdmin.DropdownMenu $.widget.bridge 'aaDropdownMenu', ActiveAdmin.DropdownMenu -$(document).on 'ready page:load', -> +$(document).on 'ready page:load turbolinks:load', -> $('.dropdown_menu').aaDropdownMenu() From 40159f82f32cc52c329dc216bb3c0db3b63d18ad Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Thu, 23 Jun 2016 23:46:24 +0800 Subject: [PATCH 0125/3836] Add missing translations for zh-TW --- config/locales/zh-TW.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 0e9c1d4d81e..d0163757d10 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -73,12 +73,15 @@ labels: destroy: "刪除" comments: + created_at: "建立" resource_type: "資源種類" author_type: "作者身份" body: "內文" author: "作者" title: "評論" add: "新增評論" + delete: "刪除評論" + delete_confirmation: "你確定要刪除這些評論嗎?" resource: "資源" no_comments_yet: "尚無評論" author_missing: "匿名" @@ -126,3 +129,8 @@ turn_off_compatibility_view: "若您是使用 IE 9 或更新的版本,請確認「相容性檢視」是關閉的。" access_denied: message: "您沒有權限執行此項操作" + index_list: + table: "表格" + block: "清單" + grid: "格狀" + blog: "部落格" From e567fe582fe039e85ec651e5ff3e12bda3e78af9 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Mon, 27 Jun 2016 13:01:54 +0200 Subject: [PATCH 0126/3836] remove double expection --- spec/unit/views/components/paginated_collection_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/unit/views/components/paginated_collection_spec.rb b/spec/unit/views/components/paginated_collection_spec.rb index 1a678e635d7..7c54f82e0cb 100644 --- a/spec/unit/views/components/paginated_collection_spec.rb +++ b/spec/unit/views/components/paginated_collection_spec.rb @@ -212,7 +212,6 @@ def paginated_collection(*args) describe "set to false" do it "should not show the total item counts" do - expect(collection).not_to receive(:total_pages) expect(collection).not_to receive(:total_pages) pagination = paginated_collection(collection, pagination_total: false) info = pagination.find_by_class('pagination_information').first.content.gsub(' ',' ') From 7ccc81627730892227b3d8e72ff74622fe7451ed Mon Sep 17 00:00:00 2001 From: Anton Smirnov Date: Thu, 19 May 2016 15:17:35 +0300 Subject: [PATCH 0127/3836] fix ActionDispatch::Reloader.to_prepare and ActionDispatch::Reloader.to_cleanup deprecation warning in Rails 5 --- lib/active_admin/application.rb | 7 ++++--- lib/active_admin/reloader.rb | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 lib/active_admin/reloader.rb diff --git a/lib/active_admin/application.rb b/lib/active_admin/application.rb index ff10e023741..0214f64b4b1 100644 --- a/lib/active_admin/application.rb +++ b/lib/active_admin/application.rb @@ -1,4 +1,5 @@ require 'active_admin/router' +require 'active_admin/reloader' require 'active_admin/helpers/settings' module ActiveAdmin @@ -282,11 +283,11 @@ def attach_reloader # Rails is about to unload all the app files (e.g. models), so we # should first unload the classes generated by Active Admin, otherwise # they will contain references to the stale (unloaded) classes. - ActionDispatch::Reloader.to_prepare(prepend: true, &unload_active_admin) + Reloader.to_prepare(prepend: true, &unload_active_admin) else # If the user has configured the app to always reload app files after # each request, so we should unload the generated classes too. - ActionDispatch::Reloader.to_cleanup(&unload_active_admin) + Reloader.to_complete(&unload_active_admin) end admin_dirs = {} @@ -301,7 +302,7 @@ def attach_reloader app.reloaders << routes_reloader - ActionDispatch::Reloader.to_prepare do + Reloader.to_prepare do # Rails might have reloaded the routes for other reasons (e.g. # routes.rb has changed), in which case Active Admin would have been # loaded via the `ActiveAdmin.routes` call in `routes.rb`. diff --git a/lib/active_admin/reloader.rb b/lib/active_admin/reloader.rb new file mode 100644 index 00000000000..a84e8010e98 --- /dev/null +++ b/lib/active_admin/reloader.rb @@ -0,0 +1,25 @@ +module ActiveAdmin + module Reloader + # ActionDispatch::Reloader.to_prepare is deprecated in Rails 5.0 and will be removed from Rails 5.1 + # + # Use ActiveSupport::Reloader if available for Rails 5, fall back to ActionDispatch::Reloader for earlier Rails + def self.to_prepare(*args, &block) + if defined? ActiveSupport::Reloader + ActiveSupport::Reloader.to_prepare(*args, &block) + else + ActionDispatch::Reloader.to_prepare(*args, &block) + end + end + + # ActionDispatch::Reloader.to_cleanup is deprecated in Rails 5.0 and will be removed from Rails 5.1 + # + # Use ActiveSupport::Reloader if available for Rails 5, fall back to ActionDispatch::Reloader for earlier Rails + def self.to_complete(*args, &block) + if defined? ActiveSupport::Reloader + ActiveSupport::Reloader.to_complete(*args, &block) + else + ActionDispatch::Reloader.to_cleanup(*args, &block) + end + end + end +end From 323fc2bd97c41aa98cdb013cf4684e2ae5554ec8 Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Fri, 24 Jun 2016 02:33:36 +0800 Subject: [PATCH 0128/3836] Fix Capybara compatibility issue --- features/support/env.rb | 3 +++ spec/rails_helper.rb | 3 +++ 2 files changed, 6 insertions(+) diff --git a/features/support/env.rb b/features/support/env.rb index 8d490a059ad..eaf20d4daab 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -58,6 +58,9 @@ # steps to use the XPath syntax. Capybara.default_selector = :css +# Make input type=hidden visible +Capybara.ignore_hidden_elements = false + # If you set this to false, any error raised from within your app will bubble # up to your step definition and out to cucumber unless you catch it somewhere # on the way. You can make Rails rescue errors and render error pages on a diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 7ea42b8946d..407cc95f26e 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -164,3 +164,6 @@ def with_translation(translation) config.after(:all) { DeferredGarbageCollection.reconsider } end end + +# Make input type=hidden visible +Capybara.ignore_hidden_elements = false From 458e84aad903a30424e9101fbad22cc068c03a34 Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Fri, 24 Jun 2016 15:02:44 +0800 Subject: [PATCH 0129/3836] Upgrade JRuby version --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d63ad735305..a40cb2de6b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ script: rvm: - 1.9 - 2.3.0 - - jruby-9.0.4.0 + - jruby-9.0.5.0 env: matrix: - RAILS=3.2.22 @@ -29,7 +29,7 @@ matrix: allow_failures: - rvm: 2.3.0 env: RAILS="> 5.x" - - rvm: jruby-9.0.4.0 + - rvm: jruby-9.0.5.0 env: RAILS="> 5.x" branches: only: From fe04114d597cd857dcae055af5b2520db5094f7f Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Mon, 27 Jun 2016 20:19:37 +0800 Subject: [PATCH 0130/3836] Lock listen version on Ruby 1.9 --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index bbef0e24795..977db38f132 100644 --- a/Gemfile +++ b/Gemfile @@ -61,6 +61,7 @@ group :test do gem 'cucumber', '1.3.20' gem 'database_cleaner' if rails_version != '> 5.x' gem 'guard-rspec', require: false + gem 'listen', '~> 2.7', platforms: :ruby_19 gem 'jasmine' gem 'jslint_on_rails' gem 'launchy' From 76ae1192c49401f0e3a6dc08aab13f3b466714e5 Mon Sep 17 00:00:00 2001 From: Ivan Novikov Date: Thu, 10 Mar 2016 21:41:12 +0300 Subject: [PATCH 0131/3836] Fix ActiveAdmin::Inputs::Filters::DateRangeInput cover last day --- lib/active_admin/inputs/filters/date_range_input.rb | 4 ++-- lib/ransack_ext.rb | 8 ++++++++ spec/unit/filters/filter_form_builder_spec.rb | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/active_admin/inputs/filters/date_range_input.rb b/lib/active_admin/inputs/filters/date_range_input.rb index af176a49409..11821351c73 100644 --- a/lib/active_admin/inputs/filters/date_range_input.rb +++ b/lib/active_admin/inputs/filters/date_range_input.rb @@ -15,12 +15,12 @@ def to_html end def gt_input_name - "#{method}_gteq" + "#{method}_gteq_date" end alias :input_name :gt_input_name def lt_input_name - "#{method}_lteq" + "#{method}_lteq_date" end def input_html_options(input_name = gt_input_name) diff --git a/lib/ransack_ext.rb b/lib/ransack_ext.rb index e73b92a61f0..a4e2c66ca62 100644 --- a/lib/ransack_ext.rb +++ b/lib/ransack_ext.rb @@ -9,4 +9,12 @@ {'equals'=>'eq', 'greater_than'=>'gt', 'less_than'=>'lt'}.each do |old,current| config.add_predicate old, arel_predicate: current end + + config.add_predicate 'gteq_date', + arel_predicate: 'gteq', + formatter: ->(v) { v.beginning_of_day } + + config.add_predicate 'lteq_date', + arel_predicate: 'lt', + formatter: ->(v) { v + 1.day } end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 9c6c99db08b..17c8aeca974 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -157,13 +157,13 @@ def filter(name, options = {}) let(:body) { Capybara.string(filter :created_at) } it "should generate a date greater than" do - expect(body).to have_selector("input.datepicker[name='q[created_at_gteq]']") + expect(body).to have_selector("input.datepicker[name='q[created_at_gteq_date]']") end it "should generate a seperator" do expect(body).to have_selector("span.seperator") end it "should generate a date less than" do - expect(body).to have_selector("input.datepicker[name='q[created_at_lteq]']") + expect(body).to have_selector("input.datepicker[name='q[created_at_lteq_date]']") end end From daa14908cbeb4a9ee130db56261e3226c91a63f2 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 30 Jun 2016 19:30:07 +0200 Subject: [PATCH 0132/3836] release 1.0.0.pre3 --- lib/active_admin/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/version.rb b/lib/active_admin/version.rb index 2758f11cdf9..927a9fa0889 100644 --- a/lib/active_admin/version.rb +++ b/lib/active_admin/version.rb @@ -1,3 +1,3 @@ module ActiveAdmin - VERSION = '1.0.0.pre2' + VERSION = '1.0.0.pre3' end From 23be8c68d855d46d2c225ad2ab95956042ceabfc Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 30 Jun 2016 20:18:24 +0200 Subject: [PATCH 0133/3836] list 1.0.0.pre3 in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39f908d95db..a530571f3b2 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ gem 'activeadmin', github: 'activeadmin' Or you can using rubygems: ```ruby -gem 'activeadmin', '~> 1.0.0.pre2' +gem 'activeadmin', '~> 1.0.0.pre3' ``` *Keep in mind that during the time where we use `pre`-release label, things can break in each release!* From 9e48f43ea930edcf3508ad5300987c8ee551bfd8 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Fri, 1 Jul 2016 03:58:53 +0200 Subject: [PATCH 0134/3836] allow rails 5.0 --- activeadmin.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index 71cb96cc4dd..f5da8c34766 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency 'jquery-rails' s.add_dependency 'jquery-ui-rails' s.add_dependency 'kaminari', '~> 0.15' - s.add_dependency 'rails', '>= 3.2', '< 5.0' + s.add_dependency 'rails', '>= 3.2', '< 5.1' s.add_dependency 'ransack', '~> 1.3' s.add_dependency 'sass-rails' s.add_dependency 'sprockets', '< 4' From 76a382a612b4a00bd0bc97e1c01099f40b20a0f4 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Fri, 1 Jul 2016 03:59:15 +0200 Subject: [PATCH 0135/3836] release 1.0.0.pre4 --- README.md | 2 +- lib/active_admin/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a530571f3b2..01ce9530b1d 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ gem 'activeadmin', github: 'activeadmin' Or you can using rubygems: ```ruby -gem 'activeadmin', '~> 1.0.0.pre3' +gem 'activeadmin', '~> 1.0.0.pre4' ``` *Keep in mind that during the time where we use `pre`-release label, things can break in each release!* diff --git a/lib/active_admin/version.rb b/lib/active_admin/version.rb index 927a9fa0889..6c3c2178bfd 100644 --- a/lib/active_admin/version.rb +++ b/lib/active_admin/version.rb @@ -1,3 +1,3 @@ module ActiveAdmin - VERSION = '1.0.0.pre3' + VERSION = '1.0.0.pre4' end From 8f650d871b8bb3136897093c4cdd5369069a5adb Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Fri, 1 Jul 2016 06:07:42 +0200 Subject: [PATCH 0136/3836] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 01ce9530b1d..d5e103dd13d 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ gem 'activeadmin', '~> 1.0.0.pre4' Active Admin master has preliminary support for Rails 5. To give it a try, these Gemfile changes may be needed: ```ruby +gem 'inherited_resources', github: 'activeadmin/inherited_resources' gem 'devise', '> 4.x' gem 'rspec-rails', '>= 3.5.0.beta1' gem 'ransack', github: 'activerecord-hackery/ransack' From f7547d449a5956b53c4ff041e52b1e9ac49ffd0e Mon Sep 17 00:00:00 2001 From: Richard Lee Date: Fri, 1 Jul 2016 19:35:15 +0800 Subject: [PATCH 0137/3836] Use pre-installed version of phantomjs on CI --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 977db38f132..ee7b7770d0e 100644 --- a/Gemfile +++ b/Gemfile @@ -63,6 +63,7 @@ group :test do gem 'guard-rspec', require: false gem 'listen', '~> 2.7', platforms: :ruby_19 gem 'jasmine' + gem 'phantomjs', '1.9.8.0' # Same version as Travis CI's pre-installed version gem 'jslint_on_rails' gem 'launchy' gem 'rails-i18n' # Provides default i18n for many languages From 01b2c3b9c9ab02c5b187996b3a39fa5f076f47e2 Mon Sep 17 00:00:00 2001 From: Hirofumi Wakasugi Date: Wed, 6 Jul 2016 12:01:33 +0900 Subject: [PATCH 0138/3836] Remove specifying kaminari version requirement for Rails 5 from Readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index d5e103dd13d..6246552f33b 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ gem 'inherited_resources', github: 'activeadmin/inherited_resources' gem 'devise', '> 4.x' gem 'rspec-rails', '>= 3.5.0.beta1' gem 'ransack', github: 'activerecord-hackery/ransack' -gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable' gem 'formtastic', github: 'justinfrench/formtastic' gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587' # To fix a Draper deprecation error From 24d419db0daab6a70a3904af18f7b5cf725b4de8 Mon Sep 17 00:00:00 2001 From: Jacob Kjeldahl Date: Thu, 7 Jul 2016 09:28:10 +0200 Subject: [PATCH 0139/3836] Adds turbolinks support to PerPage selector and CheckBoxToggler --- .../active_admin/lib/checkbox-toggler.js.coffee | 8 ++++++++ .../javascripts/active_admin/lib/per_page.js.coffee | 12 ++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee b/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee index 57be96e4f78..4b7800b59a6 100644 --- a/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee +++ b/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee @@ -33,4 +33,12 @@ class ActiveAdmin.CheckboxToggler $(el).prop checked: setting @_didChangeCheckbox(el) + option: (key, value) -> + if $.isPlainObject(key) + @options = $.extend(true, @options, key) + else if key? + @options[key] + else + @options[key] = value + $.widget.bridge 'checkboxToggler', ActiveAdmin.CheckboxToggler diff --git a/app/assets/javascripts/active_admin/lib/per_page.js.coffee b/app/assets/javascripts/active_admin/lib/per_page.js.coffee index 08ea65c836d..03db165a6f4 100644 --- a/app/assets/javascripts/active_admin/lib/per_page.js.coffee +++ b/app/assets/javascripts/active_admin/lib/per_page.js.coffee @@ -23,9 +23,17 @@ class ActiveAdmin.PerPage _decode: (value) -> #replace "+" before decodeURIComponent - decodeURIComponent(value.replace(/\+/g, '%20')) + decodeURIComponent(value.replace(/\+/g, '%20')) + + option: (key, value) -> + if $.isPlainObject(key) + @options = $.extend(true, @options, key) + else if key? + @options[key] + else + @options[key] = value $.widget.bridge 'perPage', ActiveAdmin.PerPage -$ -> +$(document).on 'ready page:load turbolinks:load', -> $('.pagination_per_page select').perPage() From 85e8f66b232a3b570e1bd6277f5741654af5aa6c Mon Sep 17 00:00:00 2001 From: Jacob Kjeldahl Date: Thu, 7 Jul 2016 09:30:04 +0200 Subject: [PATCH 0140/3836] Adds turbolinks visits when submitting filters and when changing number of pages for pagination --- .../active_admin/initializers/filters.js.coffee | 13 ++++++++++--- .../javascripts/active_admin/lib/per_page.js.coffee | 5 ++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/active_admin/initializers/filters.js.coffee b/app/assets/javascripts/active_admin/initializers/filters.js.coffee index 6465f9d0abd..83122fc9709 100644 --- a/app/assets/javascripts/active_admin/initializers/filters.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/filters.js.coffee @@ -1,13 +1,20 @@ $(document).on 'ready page:load turbolinks:load', -> # Clear Filters button - $('.clear_filters_btn').click -> + $('.clear_filters_btn').click (e) -> params = window.location.search.slice(1).split('&') regex = /^(q\[|q%5B|q%5b|page|commit)/ - window.location.search = (param for param in params when not param.match(regex)).join('&') + if typeof Turbolinks != 'undefined' + Turbolinks.visit(window.location.href.split('?')[0] + '?' + (param for param in params when not param.match(regex)).join('&')) + e.preventDefault() + else + window.location.search = (param for param in params when not param.match(regex)).join('&') # Filter form: don't send any inputs that are empty - $('.filter_form').submit -> + $('.filter_form').submit (e) -> $(@).find(':input').filter(-> @value is '').prop 'disabled', true + if typeof Turbolinks != 'undefined' + Turbolinks.visit(window.location.href.split('?')[0] + '?' + $( this ).serialize()) + e.preventDefault() # Filter form: for filters that let you choose the query method from # a dropdown, apply that choice to the filter input field. diff --git a/app/assets/javascripts/active_admin/lib/per_page.js.coffee b/app/assets/javascripts/active_admin/lib/per_page.js.coffee index 03db165a6f4..dd3ba3ae2fb 100644 --- a/app/assets/javascripts/active_admin/lib/per_page.js.coffee +++ b/app/assets/javascripts/active_admin/lib/per_page.js.coffee @@ -11,7 +11,10 @@ class ActiveAdmin.PerPage @$element.change => @$params['per_page'] = @$element.val() delete @$params['page'] - location.search = $.param(@$params) + if typeof Turbolinks != 'undefined' + Turbolinks.visit(window.location.href.split('?')[0] + '?' + $.param(@$params)) + else + location.search = $.param(@$params) _queryParams: -> query = window.location.search.substring(1) From bc2910d3f0788a7137c8ef3581ab44d15c8a082a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 9 Jul 2016 11:29:18 -0300 Subject: [PATCH 0141/3836] Fix batch action pluralization Since batch actions apply to multiple records, Spanish requires the pluralized form to make sense. --- config/locales/es-MX.yml | 2 +- config/locales/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index b52bf9c6383..61db5d7f3b1 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -59,7 +59,7 @@ es-MX: other: "Se han destruido %{count} %{plural_model} con éxito" selection_toggle_explanation: "(Cambiar selección)" link: "Añadir" - action_label: "%{title} seleccionado" + action_label: "%{title} seleccionados" labels: destroy: "Borrar" comments: diff --git a/config/locales/es.yml b/config/locales/es.yml index 0d9155ff2d8..b174b6f6560 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -69,7 +69,7 @@ es: other: "Se han destruido %{count} %{plural_model} con éxito" selection_toggle_explanation: "(Cambiar selección)" link: "Añadir" - action_label: "%{title} seleccionado" + action_label: "%{title} seleccionados" labels: destroy: "Borrar" comments: From 5dd417a004ddabed1f8ff25f6599e940b5925705 Mon Sep 17 00:00:00 2001 From: Molchanov Andrey Date: Sun, 10 Jul 2016 00:51:22 +0300 Subject: [PATCH 0142/3836] Add 'active_admin.comments.created_at' translation for :ru locale --- config/locales/ru.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 632bdd4e45a..2a218047243 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -77,6 +77,7 @@ ru: labels: destroy: "Удалить" comments: + created_at: "Дата создания" resource_type: "Тип ресурса" author_type: "Тип автора" body: "Текст" From d43d3882118cd9adf60e3b08e05b9263c400c83e Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 10 Jul 2016 14:07:33 -0500 Subject: [PATCH 0143/3836] Update gem requirements for Rails 5 Currently Travis is still using Rails release candidates. This updates it to use the proper release. It also gets it back in sync with the README. I released Draper 3.0.0.pre1. A lot of other gems have published Rails 5 compatible versions to Rubygems. This fixes a Devise deprecation warning: > including `Devise::TestHelpers` is deprecated and will be removed from Devise. For controller tests, please include `Devise::Test::ControllerHelpers` instead. --- .travis.yml | 8 +++---- Gemfile | 28 ++++++++++-------------- README.md | 14 ++---------- features/step_definitions/table_steps.rb | 6 +---- spec/rails_helper.rb | 16 +++----------- 5 files changed, 22 insertions(+), 50 deletions(-) diff --git a/.travis.yml b/.travis.yml index a40cb2de6b3..76963c0dab9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,19 +18,19 @@ env: matrix: - RAILS=3.2.22 - RAILS=4.2.5 - - RAILS="> 5.x" + - RAILS=5.0.0 global: - JRUBY_OPTS="-J-Xmx1024m --debug" matrix: fast_finish: true exclude: - rvm: 1.9 - env: RAILS="> 5.x" + env: RAILS=5.0.0 allow_failures: - rvm: 2.3.0 - env: RAILS="> 5.x" + env: RAILS=5.0.0 - rvm: jruby-9.0.5.0 - env: RAILS="> 5.x" + env: RAILS=5.0.0 branches: only: - master diff --git a/Gemfile b/Gemfile index ee7b7770d0e..06900c6b72b 100644 --- a/Gemfile +++ b/Gemfile @@ -5,30 +5,26 @@ gemspec require File.expand_path 'spec/support/detect_rails_version', File.dirname(__FILE__) rails_version = detect_rails_version +rails_major = rails_version[0] + gem 'rails', rails_version -gem 'jquery-ui-rails', rails_version[0] == '3' ? '~> 4.0' : '~> 5.0' +gem 'jquery-ui-rails', rails_major == '3' ? '~> 4.0' : '~> 5.0' -gem 'test-unit', '~> 3.0' if rails_version[0] == '3' +gem 'test-unit', '~> 3.0' if rails_major == '3' -if rails_version == '> 5.x' +if rails_major == '5' # Note: when updating this list, be sure to also update the README - gem 'ransack', github: 'activerecord-hackery/ransack' - gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable' - gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587' - gem 'formtastic', github: 'justinfrench/formtastic' - gem 'activemodel-serializers-xml', github: 'rails/activemodel-serializers-xml' # drapergem/draper#697 - gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' - gem 'database_cleaner', github: 'DatabaseCleaner/database_cleaner' - gem 'activerecord-jdbc-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: :jruby + gem 'inherited_resources', github: 'activeadmin/inherited_resources' + gem 'ransack', github: 'activerecord-hackery/ransack' end gem 'mime-types', '< 3' # Remove this line when we drop support for Ruby 1.9 # Optional dependencies gem 'cancan' -gem 'devise', rails_version == '> 5.x' ? '> 4.x' : '~> 3.5' -gem 'draper' if rails_version != '> 5.x' +gem 'devise', rails_major == '5' ? '> 4.x' : '~> 3.5' +gem 'draper', rails_major == '5' ? '> 3.x' : '~> 2.1' gem 'pundit' # Utility gems used in both development & test environments @@ -44,7 +40,7 @@ group :development do gem 'binding_of_caller', platforms: :mri # Retrieve the binding of a method's caller in MRI Ruby >= 1.9.2 # Performance - gem 'rack-mini-profiler' if rails_version != '> 5.x' # Inline app profiler. See ?pp=help for options. + gem 'rack-mini-profiler' # Inline app profiler. See ?pp=help for options. gem 'flamegraph', platforms: :mri # Flamegraph visualiztion: ?pp=flamegraph # Documentation @@ -59,7 +55,7 @@ group :test do gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' - gem 'database_cleaner' if rails_version != '> 5.x' + gem 'database_cleaner' gem 'guard-rspec', require: false gem 'listen', '~> 2.7', platforms: :ruby_19 gem 'jasmine' @@ -71,6 +67,6 @@ group :test do gem 'i18n-spec' gem 'shoulda-matchers', '<= 2.8.0' gem 'sqlite3', platforms: :mri - gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby if rails_version != '> 5.x' + gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby gem 'poltergeist' end diff --git a/README.md b/README.md index 6246552f33b..12e07db3d3d 100644 --- a/README.md +++ b/README.md @@ -33,18 +33,8 @@ Active Admin master has preliminary support for Rails 5. To give it a try, these ```ruby gem 'inherited_resources', github: 'activeadmin/inherited_resources' -gem 'devise', '> 4.x' -gem 'rspec-rails', '>= 3.5.0.beta1' -gem 'ransack', github: 'activerecord-hackery/ransack' -gem 'formtastic', github: 'justinfrench/formtastic' -gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587' -# To fix a Draper deprecation error -gem 'activemodel-serializers-xml', github: 'rails/activemodel-serializers-xml' -# Optional -- only if you already include these gems -gem 'rack-mini-profiler', github: 'MiniProfiler/rack-mini-profiler' -gem 'database_cleaner', github: 'pschambacher/database_cleaner', branch: 'rails5.0', ref: '8dd9fa4' -# Only for JRuby: -gem 'activerecord-jdbc-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: :jruby +gem 'ransack', github: 'activerecord-hackery/ransack' +gem 'draper', '> 3.x' ``` If something isn't working for you please report it on [#4177](https://github.com/activeadmin/activeadmin/issues/4177). diff --git a/features/step_definitions/table_steps.rb b/features/step_definitions/table_steps.rb index 236241816ca..e803dcb98e9 100644 --- a/features/step_definitions/table_steps.rb +++ b/features/step_definitions/table_steps.rb @@ -59,8 +59,6 @@ def input_to_string(input) end module TableMatchHelper - - # @param table [Array[Array]] # @param expected_table [Array[Array[String]]] # The expected_table values are String. They are converted to @@ -97,12 +95,10 @@ def assert_cells_match(cell, expected_cell) expect((cell || "").strip).to eq expected_cell end end - -end # module TableMatchHelper +end World(TableMatchHelper) - # Usage: # # I should see the "invoices" table: diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 407cc95f26e..efcca8138af 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -86,7 +86,6 @@ def with_translation(translation) ensure I18n.backend.reload! end - end ENV['RAILS_ENV'] = 'test' @@ -121,27 +120,18 @@ def with_translation(translation) ActiveAdmin.application.authentication_method = false ActiveAdmin.application.current_user_method = false -# Don't add asset cache timestamps. Makes it easy to integration -# test for the presence of an asset file -ENV["RAILS_ASSET_ID"] = '' - RSpec.configure do |config| config.use_transactional_fixtures = true config.use_instantiated_fixtures = false - config.include Devise::TestHelpers, type: :controller + config.include Devise::Test::ControllerHelpers, type: :controller config.render_views = false config.filter_run focus: true config.filter_run_excluding skip: true config.run_all_when_everything_filtered = true config.color = true -end -# All RSpec configuration needs to happen before any examples -# or else it whines. -require "support/active_admin_request_helpers" -RSpec.configure do |c| - c.include ActiveAdminRequestHelpers, type: :request - c.include Devise::TestHelpers, type: :controller + require 'support/active_admin_request_helpers' + config.include ActiveAdminRequestHelpers, type: :request end # Force deprecations to raise an exception. From 8bf18609275df28f778c3d3dc01a7f1333cef5e7 Mon Sep 17 00:00:00 2001 From: Sean Linsley Date: Sun, 10 Jul 2016 14:22:57 -0500 Subject: [PATCH 0144/3836] Support older versions of Devise for Rails 3 & 4 --- spec/rails_helper.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index efcca8138af..6312bf2f060 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -123,13 +123,15 @@ def with_translation(translation) RSpec.configure do |config| config.use_transactional_fixtures = true config.use_instantiated_fixtures = false - config.include Devise::Test::ControllerHelpers, type: :controller config.render_views = false config.filter_run focus: true config.filter_run_excluding skip: true config.run_all_when_everything_filtered = true config.color = true + devise = ActiveAdmin::Dependency.devise >= '4.2' ? Devise::Test::ControllerHelpers : Devise::TestHelpers + config.include devise, type: :controller + require 'support/active_admin_request_helpers' config.include ActiveAdminRequestHelpers, type: :request end From 0381f3f08fe5b9edac05e6817225108ea9e74f97 Mon Sep 17 00:00:00 2001 From: Aleksandr Furmanov Date: Thu, 7 Jul 2016 15:55:45 -0600 Subject: [PATCH 0145/3836] Fixing 'inputs' - respecing other than :class options --- .../views/components/active_admin_form.rb | 17 +++++++++-------- spec/unit/form_builder_spec.rb | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/active_admin/views/components/active_admin_form.rb b/lib/active_admin/views/components/active_admin_form.rb index babb3446d4e..6441571085b 100644 --- a/lib/active_admin/views/components/active_admin_form.rb +++ b/lib/active_admin/views/components/active_admin_form.rb @@ -19,7 +19,7 @@ def to_s opening_tag << children.to_s << closing_tag end end - + class ActiveAdminForm < FormtasticProxy builder_method :active_admin_form_for @@ -95,14 +95,15 @@ def form_buffers class SemanticInputsProxy < FormtasticProxy def build(form_builder, *args, &block) - options = args.extract_options! - legend = args.shift + html_options = args.extract_options! + html_options[:class] ||= "inputs" + legend = args.shift if args.first.is_a?(::String) + legend = html_options.delete(:name) if html_options.key?(:name) legend_tag = legend ? "#{legend}" : "" - klasses = ["inputs"] - klasses << options[:class] if options[:class] - @opening_tag = "
#{legend_tag}
    " + fieldset_attrs = html_options.map {|k,v| %Q{#{k}="#{v}"} }.join(" ") + @opening_tag = "
    #{legend_tag}
      " @closing_tag = "
    " - super(*(args << options), &block) + super(*(args << html_options), &block) end end @@ -120,4 +121,4 @@ def build(form_builder, *args, &block) end end end -end \ No newline at end of file +end diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 7c774d444bb..6f4fa798388 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -71,7 +71,7 @@ def build_form(options = {}, form_object = Post.new, &block) end it "should generate a fieldset with a inputs and custom class" do - expect(body).to have_selector("fieldset.inputs.custom_class") + expect(body).to have_selector("fieldset.custom_class") end end end From 0fb65165c04a92d50b61514d6c2c299c9155c3f7 Mon Sep 17 00:00:00 2001 From: Aleksandr Furmanov Date: Mon, 11 Jul 2016 09:28:12 -0600 Subject: [PATCH 0146/3836] Adding more tests --- spec/unit/form_builder_spec.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 6f4fa798388..a37d0c976d0 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -63,7 +63,7 @@ def build_form(options = {}, form_object = Post.new, &block) context "it with custom settings" do let :body do build_form do |f| - f.inputs class: "custom_class" do + f.inputs class: "custom_class", name: 'custom_name', custom_attr: 'custom_attr' do f.input :title f.input :body end @@ -73,6 +73,14 @@ def build_form(options = {}, form_object = Post.new, &block) it "should generate a fieldset with a inputs and custom class" do expect(body).to have_selector("fieldset.custom_class") end + + it "should generate a fieldset with a custom legend" do + expect(body).to have_css("legend", text: 'custom_name') + end + + it "should generate a fieldset with a custom attributes" do + expect(body).to have_selector("fieldset[custom_attr='custom_attr']") + end end end From 487f976fb895adfb780d682d85674dc35862b72b Mon Sep 17 00:00:00 2001 From: Shai Coleman Date: Mon, 11 Jul 2016 21:33:39 +0100 Subject: [PATCH 0147/3836] Fix #4424, issue with new_with_cast from 6488d63 --- lib/active_admin/resource_controller/data_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index fc68fd09c7a..de72b9d0dbc 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -136,7 +136,7 @@ def build_resource # # @return [ActiveRecord::Base] An un-saved active record base object def build_new_resource - scoped_collection.send method_for_build + scoped_collection.send method_for_build, *resource_params end # Calls all the appropriate callbacks and then creates the new resource. From 0c9f55005f3fb8f7a3eeca57baeefa2d3ebe7446 Mon Sep 17 00:00:00 2001 From: Alexander Merkulov Date: Thu, 14 Jul 2016 21:33:21 +0300 Subject: [PATCH 0148/3836] Fix permitted params in dummy apps, for Rails 3, 4, 5 --- spec/support/rails_template.rb | 6 +++--- spec/support/rails_template_with_data.rb | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 07a69738326..dcc425919aa 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -11,7 +11,7 @@ class Post < ActiveRecord::Base accepts_nested_attributes_for :taggings unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes - attr_accessible :id, :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id + attr_accessible :id, :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id, :category end end RUBY @@ -28,7 +28,7 @@ class Blog::Post < ActiveRecord::Base accepts_nested_attributes_for :taggings unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes - attr_accessible :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id + attr_accessible :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id, :category end end RUBY @@ -68,7 +68,7 @@ class Category < ActiveRecord::Base accepts_nested_attributes_for :posts unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes - attr_accessible :name + attr_accessible :name, :description end end RUBY diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 56f6d60885b..7c00022c8fa 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -4,7 +4,26 @@ generate :'active_admin:resource', type end +inject_into_file 'app/admin/category.rb', <<-RUBY, after: "ActiveAdmin.register Category do\n" + + if Rails::VERSION::MAJOR >= 4 + permit_params [:name, :description] + end +RUBY + +inject_into_file 'app/admin/user.rb', <<-RUBY, after: "ActiveAdmin.register User do\n" + + if Rails::VERSION::MAJOR >= 4 + permit_params [:first_name, :last_name, :username, :age] + end +RUBY + inject_into_file 'app/admin/post.rb', <<-RUBY, after: "ActiveAdmin.register Post do\n" + + if Rails::VERSION::MAJOR >= 4 + permit_params [:custom_category_id, :author_id, :title, :body, :published_at, :position, :starred] + end + scope :all, default: true scope :drafts do |posts| From f57ce4585633e5801538a32eb9a615c4fec47792 Mon Sep 17 00:00:00 2001 From: Alexander Merkulov Date: Thu, 14 Jul 2016 21:31:04 +0300 Subject: [PATCH 0149/3836] Add Sprockets 4.x support. Update Rails 5 gem list in README. Generate assets/config/manifest.js for Rails 4+ dummy apps --- Gemfile | 5 +++++ README.md | 1 + activeadmin.gemspec | 2 +- spec/support/rails_template.rb | 4 ++++ spec/support/templates/manifest.js | 3 +++ 5 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 spec/support/templates/manifest.js diff --git a/Gemfile b/Gemfile index 06900c6b72b..e7b5d9dc7a8 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ gem 'test-unit', '~> 3.0' if rails_major == '3' if rails_major == '5' # Note: when updating this list, be sure to also update the README + gem 'sass-rails', github: 'rails/sass-rails' gem 'inherited_resources', github: 'activeadmin/inherited_resources' gem 'ransack', github: 'activerecord-hackery/ransack' end @@ -43,6 +44,10 @@ group :development do gem 'rack-mini-profiler' # Inline app profiler. See ?pp=help for options. gem 'flamegraph', platforms: :mri # Flamegraph visualiztion: ?pp=flamegraph + # Flamegraph dependency + gem 'stackprof', platforms: [:mri_21, :mri_22, :mri_23], require: false + gem 'fast_track', platforms: [:mri_19, :mri_20], require: false + # Documentation gem 'yard' # Documentation generator gem 'redcarpet', platforms: :mri # Markdown implementation (for yard) diff --git a/README.md b/README.md index 12e07db3d3d..21f6aa3ae39 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Active Admin master has preliminary support for Rails 5. To give it a try, these gem 'inherited_resources', github: 'activeadmin/inherited_resources' gem 'ransack', github: 'activerecord-hackery/ransack' gem 'draper', '> 3.x' +gem 'sass-rails', github: 'rails/sass-rails' # For Sprockets 4 ``` If something isn't working for you please report it on [#4177](https://github.com/activeadmin/activeadmin/issues/4177). diff --git a/activeadmin.gemspec b/activeadmin.gemspec index f5da8c34766..f9e52004a9f 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -27,5 +27,5 @@ Gem::Specification.new do |s| s.add_dependency 'rails', '>= 3.2', '< 5.1' s.add_dependency 'ransack', '~> 1.3' s.add_dependency 'sass-rails' - s.add_dependency 'sprockets', '< 4' + s.add_dependency 'sprockets', '< 4.1' end diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 07a69738326..e0420a78d48 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -1,5 +1,9 @@ # Rails template to build the sample app for specs +if Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR >= 2 + copy_file File.expand_path('../templates/manifest.js', __FILE__), 'app/assets/config/manifest.js', force: true +end + generate :model, 'post title:string body:text published_at:datetime author_id:integer ' + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' create_file 'app/models/post.rb', <<-RUBY.strip_heredoc, force: true diff --git a/spec/support/templates/manifest.js b/spec/support/templates/manifest.js new file mode 100644 index 00000000000..b16e53d6d56 --- /dev/null +++ b/spec/support/templates/manifest.js @@ -0,0 +1,3 @@ +//= link_tree ../images +//= link_directory ../javascripts .js +//= link_directory ../stylesheets .css From 2d70ef95dbfbde75d8a8321415556b7ad7cde2d8 Mon Sep 17 00:00:00 2001 From: Alexander Merkulov Date: Thu, 14 Jul 2016 22:19:18 +0300 Subject: [PATCH 0150/3836] Fix Cucumber specs for Arbre. --- features/specifying_actions.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/specifying_actions.feature b/features/specifying_actions.feature index 3f91d19d9fd..4bf8983b8bf 100644 --- a/features/specifying_actions.feature +++ b/features/specifying_actions.feature @@ -80,7 +80,7 @@ Feature: Specifying Actions """ Given "app/views/admin/posts/review.html.arb" contains: """ - h1 "Review: #{@post.title}" + h1 "Review: #{post.title}" """ And I am logged in And a post with the title "Hello World" exists From 580b96539ba0afece062a451dc93917373882f49 Mon Sep 17 00:00:00 2001 From: Alexander Merkulov Date: Thu, 14 Jul 2016 22:19:18 +0300 Subject: [PATCH 0151/3836] Fix Cucumber specs for Devise. --- features/step_definitions/user_steps.rb | 7 +++++++ features/users/logging_in.feature | 2 ++ 2 files changed, 9 insertions(+) diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb index 880acaaa548..bebc407c0c0 100644 --- a/features/step_definitions/user_steps.rb +++ b/features/step_definitions/user_steps.rb @@ -40,6 +40,13 @@ def ensure_user_created(email) AdminUser.where(email: email).first.update_attribute :reset_password_sent_at, 1.month.ago if expired end +Given /^override locale "([^"]*)" with "([^"]*)"$/ do |path, value| + keys_value = path.split('.') + [value] + locale_hash = keys_value.reverse.inject{|a,n| {n=>a}} + I18n.available_locales + I18n.backend.store_translations(I18n.locale, locale_hash) +end + When /^I fill in the password field with "([^"]*)"$/ do |password| fill_in 'admin_user_password', with: password end diff --git a/features/users/logging_in.feature b/features/users/logging_in.feature index f347575a775..a0935585b92 100644 --- a/features/users/logging_in.feature +++ b/features/users/logging_in.feature @@ -20,6 +20,7 @@ Feature: User Logging In And I should see the element "a[href='/admin/admin_users/1']:contains('admin@example.com')" Scenario: Attempting to log in with an incorrect email address + Given override locale "devise.failure.not_found_in_database" with "Invalid email or password." When I fill in "Email" with "not-an-admin@example.com" And I fill in "Password" with "not-my-password" And I press "Login" @@ -27,6 +28,7 @@ Feature: User Logging In And I should see "Invalid email or password." Scenario: Attempting to log in with an incorrect password + Given override locale "devise.failure.invalid" with "Invalid email or password." When I fill in "Email" with "admin@example.com" And I fill in "Password" with "not-my-password" And I press "Login" From 85ab3f5961e1fab5d5c864ba9170b5e0fd1f6548 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Sun, 17 Jul 2016 09:09:56 +0200 Subject: [PATCH 0152/3836] remove rails 5 from travis allow failures list --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 76963c0dab9..85513cd3448 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,8 +27,6 @@ matrix: - rvm: 1.9 env: RAILS=5.0.0 allow_failures: - - rvm: 2.3.0 - env: RAILS=5.0.0 - rvm: jruby-9.0.5.0 env: RAILS=5.0.0 branches: From e91134d9546bfc5e6dd33745f63084b25943d8a4 Mon Sep 17 00:00:00 2001 From: Nikita Sokolov Date: Fri, 24 Jun 2016 12:13:11 +0300 Subject: [PATCH 0153/3836] Do not decorate not found resources (nils) --- lib/active_admin/resource.rb | 2 +- spec/unit/resource_spec.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/resource.rb b/lib/active_admin/resource.rb index 65f3a149df8..363a085bb64 100644 --- a/lib/active_admin/resource.rb +++ b/lib/active_admin/resource.rb @@ -145,7 +145,7 @@ def breadcrumb def find_resource(id) resource = resource_class.public_send *method_for_find(id) - decorator_class ? decorator_class.new(resource) : resource + (decorator_class && resource) ? decorator_class.new(resource) : resource end private diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index ef35024f637..a9b8e794222 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -234,8 +234,10 @@ def config(options = {}) before do if Rails::VERSION::MAJOR >= 4 allow(Post).to receive(:find_by).with("id" => "12345") { post } + allow(Post).to receive(:find_by).with("id" => "54321") { nil } else allow(Post).to receive(:find_by_id).with("12345") { post } + allow(Post).to receive(:find_by_id).with("54321") { nil } end end @@ -248,6 +250,10 @@ def config(options = {}) it 'decorates the resource' do expect(resource.find_resource('12345')).to eq PostDecorator.new(post) end + + it 'does not decorate a not found resource' do + expect(resource.find_resource('54321')).to equal nil + end end context 'when using a nonstandard primary key' do From 91392b708da0c23e914523d5a8bde17d9fec121c Mon Sep 17 00:00:00 2001 From: Kasper Timm Hansen Date: Tue, 19 Jul 2016 22:06:44 +0200 Subject: [PATCH 0154/3836] Add back pretty formatting of non-symbol attributes. 3efb3595, switched around a bunch of code, but also scoped `pretty_format`-ing to only symbol attributes. This broke formatting in our app. In Active Admin v1.0.0.pre2 code like: ```ruby show do attributes_table do row :mobile_subscription do subscription # ActiveRecord::Base object. end end end ``` would auto link the returned model, but pre4 merely returns a `inspect` like output. I think scoping `pretty_format` to only symbol attributes was an oversight as the method clearly knows how to handle lots of different objects. This refines `format_attribute` so we can still get nice status tags for boolean fields, but get pretty formatted output for the rest of the values like pre2 and earlier did. --- lib/active_admin/view_helpers/display_helper.rb | 11 ++++++++--- spec/unit/view_helpers/display_helper_spec.rb | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/active_admin/view_helpers/display_helper.rb b/lib/active_admin/view_helpers/display_helper.rb index cec3dfa981a..b368af99698 100644 --- a/lib/active_admin/view_helpers/display_helper.rb +++ b/lib/active_admin/view_helpers/display_helper.rb @@ -42,9 +42,14 @@ def association_methods_for(resource) def format_attribute(resource, attr) value = find_value resource, attr - value = pretty_format value if attr.is_a? Symbol - value = Arbre::Context.new{ status_tag value } if boolean_attr? resource, attr - value + + if value.is_a?(Arbre::Element) + value + elsif boolean_attr?(resource, attr) + Arbre::Context.new { status_tag value } + else + pretty_format value + end end def find_value(resource, attr) diff --git a/spec/unit/view_helpers/display_helper_spec.rb b/spec/unit/view_helpers/display_helper_spec.rb index 35305bbf792..bad44c99711 100644 --- a/spec/unit/view_helpers/display_helper_spec.rb +++ b/spec/unit/view_helpers/display_helper_spec.rb @@ -89,7 +89,7 @@ class ThisModel it 'calls the provided block to format the value' do value = format_attribute double(foo: 2), ->r { r.foo + 1 } - expect(value).to eq 3 + expect(value).to eq '3' end it 'finds values as methods' do @@ -104,7 +104,7 @@ class ThisModel expect(value).to eq '100' end - [1, 1.2, :a_symbol, Arbre::Element.new].each do |val| + [1, 1.2, :a_symbol].each do |val| it "calls to_s to format the value of type #{val.class}" do value = format_attribute double(foo: val), :foo From 06b2628bf400a61d6099948fc9aa6ad7b63aafca Mon Sep 17 00:00:00 2001 From: Sergey Nartimov Date: Thu, 7 Jul 2016 19:04:15 +0300 Subject: [PATCH 0155/3836] Depend only on specific Rails components Rails 5 introduces Action Cable that comes with additional dependencies. Not all applications use Action Cable, so developers can choose to include only required Rails components to their Gemfiles to avoid having unused dependencies. Removing the dependency on `rails` meta gem will allow using ActiveAdmin in the applications where the developers decided to opt-out of some of the Rails components. --- activeadmin.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index f9e52004a9f..e20184d74ee 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency 'jquery-rails' s.add_dependency 'jquery-ui-rails' s.add_dependency 'kaminari', '~> 0.15' - s.add_dependency 'rails', '>= 3.2', '< 5.1' + s.add_dependency 'railties', '>= 3.2', '< 5.1' s.add_dependency 'ransack', '~> 1.3' s.add_dependency 'sass-rails' s.add_dependency 'sprockets', '< 4.1' From d94d7cacbdb5460cd8643bf985ce76c814fa877f Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 1 Aug 2016 14:23:27 -0400 Subject: [PATCH 0156/3836] Update filter example to use "_action" in name Since this gem supports Rails 4 and 5 now going forward I thought it would be better despite this being commented out that it should use the current accepted filter name `before_action` since anything suffixed with `_filter` is deprecated in Rails 5. --- .../active_admin/install/templates/active_admin.rb.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/active_admin/install/templates/active_admin.rb.erb b/lib/generators/active_admin/install/templates/active_admin.rb.erb index 8fc53b35c44..a287b004bf8 100644 --- a/lib/generators/active_admin/install/templates/active_admin.rb.erb +++ b/lib/generators/active_admin/install/templates/active_admin.rb.erb @@ -145,7 +145,7 @@ ActiveAdmin.setup do |config| # You can add before, after and around filters to all of your # Active Admin resources and pages from here. # - # config.before_filter :do_something_awesome + # config.before_action :do_something_awesome # == Localize Date/Time Format # From ccb6fac06c2633c335c441dd2587a6880d42b39d Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Sun, 7 Aug 2016 17:29:14 +0200 Subject: [PATCH 0157/3836] test all branches on travis revert f57c5a6a416cdac972d8176641aafb9bca7a62d7b --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85513cd3448..dc45faba655 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,10 +29,6 @@ matrix: allow_failures: - rvm: jruby-9.0.5.0 env: RAILS=5.0.0 -branches: - only: - - master - - /\A\d-\d-stable\z/ notifications: irc: channels: From 2b4e690d07ad960dfec83242b3ca05a4b84fd394 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Mon, 8 Aug 2016 08:24:27 +0200 Subject: [PATCH 0158/3836] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e575aba7b9c..af009998cc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ * JavaScript `window.AA` has been removed, use `window.ActiveAdmin` [#3606][] by [@timoschilling][] * `f.form_buffers` has been removed [#3486][] by [@varyonic][] * Iconic has been removed [#3553][] by [@timoschilling][] -* `config.show_comments_in_menu` has been removed [#4187][] by [@drn][] +* `config.show_comments_in_menu` has been removed, see `config.comments_menu` [#4187][] by [@drn][] ### Enhancements @@ -100,9 +100,11 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [#3695]: https://github.com/activeadmin/activeadmin/issues/3695 [#3731]: https://github.com/activeadmin/activeadmin/issues/3731 [#3783]: https://github.com/activeadmin/activeadmin/issues/3783 +[#4187]: https://github.com/activeadmin/activeadmin/issues/4187 [@PChambino]: https://github.com/PChambino [@TimPetricola]: https://github.com/TimPetricola [@chancancode]: https://github.com/chancancode +[@drn]: https://github.com/drn [@dmitry]: https://github.com/dmitry [@gonzedge]: https://github.com/gonzedge [@johnnyshields]: https://github.com/johnnyshields From 3941e1550c4d5d8a6df51057d0517f1a51b609e4 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Mon, 8 Aug 2016 08:26:16 +0200 Subject: [PATCH 0159/3836] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af009998cc5..4f492759615 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,11 +89,13 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [#2541]: https://github.com/activeadmin/activeadmin/issues/2541 [#2544]: https://github.com/activeadmin/activeadmin/issues/2544 [#2545]: https://github.com/activeadmin/activeadmin/issues/2545 +[#3038]: https://github.com/activeadmin/activeadmin/issues/3038 [#3075]: https://github.com/activeadmin/activeadmin/issues/3075 [#3463]: https://github.com/activeadmin/activeadmin/issues/3463 [#3464]: https://github.com/activeadmin/activeadmin/issues/3464 [#3486]: https://github.com/activeadmin/activeadmin/issues/3486 [#3519]: https://github.com/activeadmin/activeadmin/issues/3519 +[#3535]: https://github.com/activeadmin/activeadmin/issues/3535 [#3553]: https://github.com/activeadmin/activeadmin/issues/3553 [#3606]: https://github.com/activeadmin/activeadmin/issues/3606 [#3686]: https://github.com/activeadmin/activeadmin/issues/3686 @@ -104,6 +106,7 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [@PChambino]: https://github.com/PChambino [@TimPetricola]: https://github.com/TimPetricola [@chancancode]: https://github.com/chancancode +[@craigmcnamara]: https://github.com/craigmcnamara [@drn]: https://github.com/drn [@dmitry]: https://github.com/dmitry [@gonzedge]: https://github.com/gonzedge From 60814f7e81cd1598ece756ad4f57684536656851 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Thu, 11 Aug 2016 10:08:45 +0100 Subject: [PATCH 0160/3836] Document known issue on scaffolding and inherited_resources --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 21f6aa3ae39..833dd086925 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,22 @@ Github [docs](https://github.com/activeadmin/activeadmin/tree/master/docs#active Check out [the docs](https://github.com/activeadmin/activeadmin/blob/master/docs/0-installation.md)! +## Known issues + +### Rails 5 scaffold generators + +Active Admin requires the `inherited_resources` gem which may break scaffolding under Rails 5 as it replaces the default scaffold generator. The solution is to configure the default controller in `config/application.rb` as outlined in [josevalim/inherited_resources#195](https://github.com/josevalim/inherited_resources/issues/195) + +``` +module SampleApp + class Application < Rails::Application + ... + config.app_generators.scaffold_controller = :scaffold_controller + ... + end +end +``` + ## Need help? Ask us in IRC ([#activeadmin](https://webchat.freenode.net/?channels=activeadmin)), on the From d32d4c7cea92155c76e1425aa450b0fa835a0662 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 11 Aug 2016 20:38:36 +0200 Subject: [PATCH 0161/3836] Revert "force usage of jQuery 2 from jquery-rails" --- app/assets/javascripts/active_admin/base.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/active_admin/base.js.coffee b/app/assets/javascripts/active_admin/base.js.coffee index ea5cfa82241..6f184cafcc5 100644 --- a/app/assets/javascripts/active_admin/base.js.coffee +++ b/app/assets/javascripts/active_admin/base.js.coffee @@ -1,4 +1,4 @@ -#= require jquery2 +#= require jquery #= require ./jquery_ui #= require jquery_ujs #= require_self From eef615484507cd5af0fdbb5aa2ba01642f18d6fd Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 11 Aug 2016 22:41:37 +0200 Subject: [PATCH 0162/3836] Revert "Document known issue on scaffolding and inherited_resources" --- README.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/README.md b/README.md index 833dd086925..21f6aa3ae39 100644 --- a/README.md +++ b/README.md @@ -74,22 +74,6 @@ Github [docs](https://github.com/activeadmin/activeadmin/tree/master/docs#active Check out [the docs](https://github.com/activeadmin/activeadmin/blob/master/docs/0-installation.md)! -## Known issues - -### Rails 5 scaffold generators - -Active Admin requires the `inherited_resources` gem which may break scaffolding under Rails 5 as it replaces the default scaffold generator. The solution is to configure the default controller in `config/application.rb` as outlined in [josevalim/inherited_resources#195](https://github.com/josevalim/inherited_resources/issues/195) - -``` -module SampleApp - class Application < Rails::Application - ... - config.app_generators.scaffold_controller = :scaffold_controller - ... - end -end -``` - ## Need help? Ask us in IRC ([#activeadmin](https://webchat.freenode.net/?channels=activeadmin)), on the From 22bbf247788f3564a8b2e3b0bf0119cad076550d Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 11 Aug 2016 22:53:26 +0200 Subject: [PATCH 0163/3836] update rails 5 readme section --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 21f6aa3ae39..7b1ebaf4422 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,6 @@ Active Admin master has preliminary support for Rails 5. To give it a try, these ```ruby gem 'inherited_resources', github: 'activeadmin/inherited_resources' -gem 'ransack', github: 'activerecord-hackery/ransack' -gem 'draper', '> 3.x' -gem 'sass-rails', github: 'rails/sass-rails' # For Sprockets 4 ``` If something isn't working for you please report it on [#4177](https://github.com/activeadmin/activeadmin/issues/4177). From 15820510e4ba3c81dbfeb966f237380123304404 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 11 Aug 2016 22:54:08 +0200 Subject: [PATCH 0164/3836] remove rails 5 collection issue from readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 7b1ebaf4422..c0fd4d8d86e 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,6 @@ Active Admin master has preliminary support for Rails 5. To give it a try, these gem 'inherited_resources', github: 'activeadmin/inherited_resources' ``` -If something isn't working for you please report it on [#4177](https://github.com/activeadmin/activeadmin/issues/4177). - ### 0.6.x The plan is to follow [semantic versioning](http://semver.org/) as of 1.0.0. The 0.6.x line will From 7d3edca75916d478fcfbb1f03c02773f2019f444 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Thu, 11 Aug 2016 22:17:55 +0100 Subject: [PATCH 0165/3836] Document known issue on scaffolding and inherited_resources --- docs/14-gotchas.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index d0f7fd162d2..15972f30146 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -95,6 +95,22 @@ YourModel.__elasticsearch__.search ```ruby YourModel.solr_search ``` + +### Rails 5 scaffold generators + +Active Admin requires the `inherited_resources` gem which may break scaffolding under Rails 5 as it replaces the default scaffold generator. The solution is to configure the default controller in `config/application.rb` as outlined in [josevalim/inherited_resources#195](https://github.com/josevalim/inherited_resources/issues/195) + +``` +module SampleApp + class Application < Rails::Application + ... + config.app_generators.scaffold_controller = :scaffold_controller + ... + end +end +``` + + ## Authentication & Application Controller The `ActiveAdmin::BaseController` inherits from the `ApplicationController`. Any authentication method(s) specified in the `ApplicationController` callbacks will be called instead of the authentication method in the active admin config file. For example, if the ApplicationController has a callback `before_action :custom_authentication_method` and the config file's authentication method is `config.authentication_method = :authenticate_active_admin_user`, then `custom_authentication_method` will be called instead of `authenticate_active_admin_user`. From 1e7a5b43992a871ef39c8910ff94faf8216849ba Mon Sep 17 00:00:00 2001 From: Tony Wong Date: Sun, 21 Aug 2016 19:25:36 -0400 Subject: [PATCH 0166/3836] Fix example sidebar access to resource usage I couldn't get the example to work with the `project` variable. Looking at the guide for sidebar [https://github.com/activeadmin/activeadmin/blob/master/docs/7-sidebars.md], it seems like the correct variable is `resource`. --- docs/2-resource-customization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index 8464b3a03b0..cc7c59ad71c 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -364,8 +364,8 @@ ActiveAdmin.register Project do sidebar "Project Details", only: [:show, :edit] do ul do - li link_to "Tickets", admin_project_tickets_path(project) - li link_to "Milestones", admin_project_milestones_path(project) + li link_to "Tickets", admin_project_tickets_path(resource) + li link_to "Milestones", admin_project_milestones_path(resource) end end end From b10b81c8d1e0123b4d9d58474503ae8e5f010e8a Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Tue, 23 Aug 2016 11:23:57 +0200 Subject: [PATCH 0167/3836] let MethodOrProcHelper's return the symbol_or_proc as fallback --- lib/active_admin/view_helpers/method_or_proc_helper.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/view_helpers/method_or_proc_helper.rb b/lib/active_admin/view_helpers/method_or_proc_helper.rb index ba23a880d27..ee79cf5e121 100644 --- a/lib/active_admin/view_helpers/method_or_proc_helper.rb +++ b/lib/active_admin/view_helpers/method_or_proc_helper.rb @@ -18,6 +18,8 @@ def call_method_or_exec_proc(symbol_or_proc, *args) send(symbol_or_proc, *args) when Proc instance_exec(*args, &symbol_or_proc) + else + symbol_or_proc end end @@ -60,6 +62,8 @@ def call_method_or_proc_on(receiver, *args) else symbol_or_proc.call(receiver, *args) end + else + symbol_or_proc end end @@ -71,7 +75,7 @@ def render_or_call_method_or_proc_on(obj, string_symbol_or_proc, options = {}) case string_symbol_or_proc when Symbol, Proc call_method_or_proc_on(obj, string_symbol_or_proc, options) - when String + else string_symbol_or_proc end end From 8cd991776d2bbf79c4da1c98c9150fc8a49f8eda Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Wed, 24 Aug 2016 20:21:34 +0200 Subject: [PATCH 0168/3836] Revert "Fix #4424, issue with new_with_cast from 6488d63" --- lib/active_admin/resource_controller/data_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index de72b9d0dbc..fc68fd09c7a 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -136,7 +136,7 @@ def build_resource # # @return [ActiveRecord::Base] An un-saved active record base object def build_new_resource - scoped_collection.send method_for_build, *resource_params + scoped_collection.send method_for_build end # Calls all the appropriate callbacks and then creates the new resource. From 041058aaaad1a7b6972b9b5b82fdb162b06f49cd Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Sun, 21 Aug 2016 04:28:42 +0300 Subject: [PATCH 0169/3836] Make the has_many allow_destroy option smart When I generate nested has_many forms, I might whant to set the `allow_destroy` parameter depending on the child record. For example: I want to not allow delete comments, that was created by an admin, or I want to not allow delete articles that are published. I added the ability to specify Symbol and Proc as `allow_destroy` parameter. If a Symbol is specified, the child object's method will be called. # this will create 'delete' checkbox only for articles which #draft? method returns true f.has_many :articles, allow_destroy: :draft? do |a| If a Proc is specified, the given blok will be calculated for the child object. The object is passed as the parameter of the block. f.has_many :comments, allow_destroy: -> (comment) { !comment.author.admin? } do |c| --- lib/active_admin/form_builder.rb | 22 ++++++-- spec/unit/form_builder_spec.rb | 90 ++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 22 deletions(-) diff --git a/lib/active_admin/form_builder.rb b/lib/active_admin/form_builder.rb index 44a449390ec..57120706fe1 100644 --- a/lib/active_admin/form_builder.rb +++ b/lib/active_admin/form_builder.rb @@ -59,7 +59,7 @@ def has_many(assoc, options = {}, &block) block.call has_many_form, index template.concat has_many_actions(has_many_form, builder_options, "".html_safe) end - + template.assign(has_many_block: true) contents = without_wrapper { inputs(options, &form_block) } || "".html_safe @@ -83,10 +83,12 @@ def has_many_actions(has_many_form, builder_options, contents) contents << template.content_tag(:li) do template.link_to I18n.t('active_admin.has_many_remove'), "#", class: 'button has_many_remove' end - elsif builder_options[:allow_destroy] - has_many_form.input(:_destroy, as: :boolean, - wrapper_html: {class: 'has_many_delete'}, - label: I18n.t('active_admin.has_many_delete')) + elsif builder_options.key? :allow_destroy + if allow_destroy?(has_many_form.object, builder_options.fetch(:allow_destroy)) + has_many_form.input(:_destroy, as: :boolean, + wrapper_html: {class: 'has_many_delete'}, + label: I18n.t('active_admin.has_many_delete')) + end end if builder_options[:sortable] @@ -137,5 +139,15 @@ def js_for_has_many(assoc, form_block, template, new_record, class_string) } end + def allow_destroy?(object, allow_destroy_option) + case allow_destroy_option + when Symbol + object.public_send allow_destroy_option + when Proc + allow_destroy_option.call(object) + else + allow_destroy_option + end + end end end diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index a37d0c976d0..db761fde28a 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -2,7 +2,6 @@ require "rspec/mocks/standalone" describe ActiveAdmin::FormBuilder do - # Setup an ActionView::Base object which can be used for # generating the form for. let(:helpers) do @@ -510,7 +509,6 @@ def user it "should add a custom header" do expect(body).to have_selector("h3", text: "Post") end - end describe "without heading and new record link" do @@ -549,7 +547,6 @@ def user it "should add a custom header" do expect(body).to have_selector("h3", "Test heading") end - end describe "with custom new record link" do @@ -565,33 +562,92 @@ def user it "should add a custom new record link" do expect(body).to have_selector("a", text: "My Custom New Post") end - end describe "with allow destroy" do context "with an existing post" do - let :body do - s = self - build_form({url: '/categories'}, Category.new) do |f| - s.instance_exec do - allow(f.object.posts.build).to receive(:new_record?).and_return(false) + + shared_examples_for "has many persisted with allow_destroy as boolean" do + it "should include a boolean field for _destroy" do + expect(body).to have_selector("input[name='category[posts_attributes][0][_destroy]']") + end + + it "should have a check box with 'Remove' as its label" do + expect(body).to have_selector("label[for=category_posts_attributes_0__destroy]", text: "Delete") + end + + it "should wrap the destroy field in an li with class 'has_many_delete'" do + expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1) + end + end + + shared_examples_for "has many persisted with allow_destroy as Symbol or Proc" do |allow_destroy_option| + let :body do + s = self + build_form({url: '/categories'}, Category.new) do |f| + s.instance_exec do + allow(f.object.posts.build).to receive(:foo?).and_return(true) + allow(f.object.posts.build).to receive(:foo?).and_return(false) + + f.object.posts.each do |post| + allow(post).to receive(:new_record?).and_return(false) + end + end + f.has_many :posts, allow_destroy: allow_destroy_option do |p| + p.input :title + end end - f.has_many :posts, allow_destroy: true do |p| - p.input :title + end + + before(:each) do + expect(body).to have_selector("input[name='category[posts_attributes][0][title]']") + expect(body).to have_selector("input[name='category[posts_attributes][1][title]']") + end + + it_behaves_like "has many persisted with allow_destroy as boolean" + + it "should not include a boolean field for _destroy" do + expect(body).to_not have_selector("input[name='category[posts_attributes][1][_destroy]']") + end + + it "should not have a check box with 'Remove' as its label" do + expect(body).to_not have_selector("label[for=category_posts_attributes_1__destroy]", text: "Delete") + end + end + + context "with allow_destroy as boolean" do + let :body do + s = self + build_form({url: '/categories'}, Category.new) do |f| + s.instance_exec do + allow(f.object.posts.build).to receive(:new_record?).and_return(false) + end + f.has_many :posts, allow_destroy: true do |p| + p.input :title + end end end + + it_behaves_like "has many persisted with allow_destroy as boolean" end - it "should include a boolean field for _destroy" do - expect(body).to have_selector("input[name='category[posts_attributes][0][_destroy]']") + context "with allow_destroy as symbol" do + it_behaves_like( + "has many persisted with allow_destroy as Symbol or Proc", :foo?) end - it "should have a check box with 'Remove' as its label" do - expect(body).to have_selector("label[for=category_posts_attributes_0__destroy]", text: "Delete") + context "with allow_destroy as proc" do + it_behaves_like( + "has many persisted with allow_destroy as Symbol or Proc", + Proc.new { |child| child.foo? } + ) end - it "should wrap the destroy field in an li with class 'has_many_delete'" do - expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1) + context "with allow_destroy as lambda" do + it_behaves_like( + "has many persisted with allow_destroy as Symbol or Proc", + -> (child) { child.foo? } + ) end end From 98d91d015c22711c2d2848482a6f455110c7c754 Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Tue, 23 Aug 2016 03:29:26 +0300 Subject: [PATCH 0170/3836] using existing helper methods --- lib/active_admin/form_builder.rb | 24 +++--- spec/unit/form_builder_spec.rb | 135 ++++++++++++++++++++----------- 2 files changed, 100 insertions(+), 59 deletions(-) diff --git a/lib/active_admin/form_builder.rb b/lib/active_admin/form_builder.rb index 57120706fe1..df499800867 100644 --- a/lib/active_admin/form_builder.rb +++ b/lib/active_admin/form_builder.rb @@ -13,6 +13,8 @@ def input_wrapping(&block) module ActiveAdmin class FormBuilder < ::Formtastic::FormBuilder + include MethodOrProcHelper + self.input_namespaces = [::Object, ::ActiveAdmin::Inputs, ::Formtastic::Inputs] # TODO: remove both class finders after formtastic 4 (where it will be default) @@ -83,12 +85,10 @@ def has_many_actions(has_many_form, builder_options, contents) contents << template.content_tag(:li) do template.link_to I18n.t('active_admin.has_many_remove'), "#", class: 'button has_many_remove' end - elsif builder_options.key? :allow_destroy - if allow_destroy?(has_many_form.object, builder_options.fetch(:allow_destroy)) - has_many_form.input(:_destroy, as: :boolean, - wrapper_html: {class: 'has_many_delete'}, - label: I18n.t('active_admin.has_many_delete')) - end + elsif has_many_allow_destroy?(has_many_form, builder_options) + has_many_form.input(:_destroy, as: :boolean, + wrapper_html: {class: 'has_many_delete'}, + label: I18n.t('active_admin.has_many_delete')) end if builder_options[:sortable] @@ -139,14 +139,14 @@ def js_for_has_many(assoc, form_block, template, new_record, class_string) } end - def allow_destroy?(object, allow_destroy_option) + def has_many_allow_destroy?(has_many_form, builder_options) + allow_destroy_option = builder_options[:allow_destroy] + case allow_destroy_option - when Symbol - object.public_send allow_destroy_option - when Proc - allow_destroy_option.call(object) + when nil then false + when TrueClass, FalseClass then allow_destroy_option else - allow_destroy_option + call_method_or_proc_on(has_many_form.object, allow_destroy_option, exec: false) end end end diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index db761fde28a..70627712092 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -565,75 +565,120 @@ def user end describe "with allow destroy" do - context "with an existing post" do + shared_examples_for "has many persisted with allow_destroy = true" do |child_num| + it "should render the nested form" do + expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][title]']") + end - shared_examples_for "has many persisted with allow_destroy as boolean" do - it "should include a boolean field for _destroy" do - expect(body).to have_selector("input[name='category[posts_attributes][0][_destroy]']") - end + it "should include a boolean field for _destroy" do + expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][_destroy]']") + end - it "should have a check box with 'Remove' as its label" do - expect(body).to have_selector("label[for=category_posts_attributes_0__destroy]", text: "Delete") - end + it "should have a check box with 'Remove' as its label" do + expect(body).to have_selector("label[for=category_posts_attributes_#{child_num}__destroy]", text: "Delete") + end + + it "should wrap the destroy field in an li with class 'has_many_delete'" do + expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1) + end + end - it "should wrap the destroy field in an li with class 'has_many_delete'" do - expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1) + shared_examples_for "has many persisted with allow_destroy = false" do |child_num| + it "should render the nested form" do + expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][title]']") + end + + it "should not have a boolean field for _destroy" do + expect(body).not_to have_selector("input[name='category[posts_attributes][#{child_num}][_destroy]']") + end + + it "should not have a check box with 'Remove' as its label" do + expect(body).not_to have_selector("label[for=category_posts_attributes_#{child_num}__destroy]", text: "Remove") + end + end + + shared_examples_for "has many persisted with allow_destroy as Symbol or Proc" do |allow_destroy_option| + let :body do + s = self + build_form({url: '/categories'}, Category.new) do |f| + s.instance_exec do + allow(f.object.posts.build).to receive(:foo?).and_return(true) + allow(f.object.posts.build).to receive(:foo?).and_return(false) + + f.object.posts.each do |post| + allow(post).to receive(:new_record?).and_return(false) + end + end + f.has_many :posts, allow_destroy: allow_destroy_option do |p| + p.input :title + end end end - shared_examples_for "has many persisted with allow_destroy as Symbol or Proc" do |allow_destroy_option| + context 'for the child that responds with true' do + it_behaves_like "has many persisted with allow_destroy = true", 0 + end + + context 'for the child that responds with false' do + it_behaves_like "has many persisted with allow_destroy = false", 1 + end + end + + context "with an existing post" do + context "with allow_destroy = true" do let :body do s = self build_form({url: '/categories'}, Category.new) do |f| s.instance_exec do - allow(f.object.posts.build).to receive(:foo?).and_return(true) - allow(f.object.posts.build).to receive(:foo?).and_return(false) - - f.object.posts.each do |post| - allow(post).to receive(:new_record?).and_return(false) - end + allow(f.object.posts.build).to receive(:new_record?).and_return(false) end - f.has_many :posts, allow_destroy: allow_destroy_option do |p| + f.has_many :posts, allow_destroy: true do |p| p.input :title end end end - before(:each) do - expect(body).to have_selector("input[name='category[posts_attributes][0][title]']") - expect(body).to have_selector("input[name='category[posts_attributes][1][title]']") - end - - it_behaves_like "has many persisted with allow_destroy as boolean" + it_behaves_like "has many persisted with allow_destroy = true", 0 + end - it "should not include a boolean field for _destroy" do - expect(body).to_not have_selector("input[name='category[posts_attributes][1][_destroy]']") + context "with allow_destroy = false" do + let :body do + s = self + build_form({url: '/categories'}, Category.new) do |f| + s.instance_exec do + allow(f.object.posts.build).to receive(:new_record?).and_return(false) + end + f.has_many :posts, allow_destroy: false do |p| + p.input :title + end + end end - it "should not have a check box with 'Remove' as its label" do - expect(body).to_not have_selector("label[for=category_posts_attributes_1__destroy]", text: "Delete") - end + it_behaves_like "has many persisted with allow_destroy = false", 0 end - context "with allow_destroy as boolean" do + context "with allow_destroy = nil" do let :body do s = self build_form({url: '/categories'}, Category.new) do |f| s.instance_exec do allow(f.object.posts.build).to receive(:new_record?).and_return(false) end - f.has_many :posts, allow_destroy: true do |p| + f.has_many :posts, allow_destroy: nil do |p| p.input :title end end end - it_behaves_like "has many persisted with allow_destroy as boolean" + it_behaves_like "has many persisted with allow_destroy = false", 0 end - context "with allow_destroy as symbol" do - it_behaves_like( - "has many persisted with allow_destroy as Symbol or Proc", :foo?) + context "with allow_destroy as Symbol" do + it_behaves_like("has many persisted with allow_destroy as Symbol or Proc", :foo?) + end + + context "with allow_destroy as String" do + it_behaves_like("has many persisted with allow_destroy as Symbol or Proc", "foo?") end context "with allow_destroy as proc" do @@ -652,21 +697,17 @@ def user end context "with a new post" do - let :body do - build_form({url: '/categories'}, Category.new) do |f| - f.object.posts.build - f.has_many :posts, allow_destroy: true do |p| - p.input :title + context "with allow_destroy = true" do + let :body do + build_form({url: '/categories'}, Category.new) do |f| + f.object.posts.build + f.has_many :posts, allow_destroy: true do |p| + p.input :title + end end end - end - it "should not have a boolean field for _destroy" do - expect(body).not_to have_selector("input[name='category[posts_attributes][0][_destroy]']") - end - - it "should not have a check box with 'Remove' as its label" do - expect(body).not_to have_selector("label[for=category_posts_attributes_0__destroy]", text: "Remove") + it_behaves_like "has many persisted with allow_destroy = false", 0 end end end From 0cac307c038d1e4751bfb9e332ea7672f6f250d2 Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Wed, 24 Aug 2016 03:24:57 +0300 Subject: [PATCH 0171/3836] Allow any other expression that evaluates to true --- lib/active_admin/form_builder.rb | 16 +++------- spec/unit/form_builder_spec.rb | 50 ++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/lib/active_admin/form_builder.rb b/lib/active_admin/form_builder.rb index df499800867..911f4e04384 100644 --- a/lib/active_admin/form_builder.rb +++ b/lib/active_admin/form_builder.rb @@ -85,7 +85,10 @@ def has_many_actions(has_many_form, builder_options, contents) contents << template.content_tag(:li) do template.link_to I18n.t('active_admin.has_many_remove'), "#", class: 'button has_many_remove' end - elsif has_many_allow_destroy?(has_many_form, builder_options) + elsif call_method_or_proc_on(has_many_form.object, + builder_options[:allow_destroy], + exec: false) + has_many_form.input(:_destroy, as: :boolean, wrapper_html: {class: 'has_many_delete'}, label: I18n.t('active_admin.has_many_delete')) @@ -138,16 +141,5 @@ def js_for_has_many(assoc, form_block, template, new_record, class_string) html: CGI.escapeHTML(html).html_safe, placeholder: placeholder } end - - def has_many_allow_destroy?(has_many_form, builder_options) - allow_destroy_option = builder_options[:allow_destroy] - - case allow_destroy_option - when nil then false - when TrueClass, FalseClass then allow_destroy_option - else - call_method_or_proc_on(has_many_form.object, allow_destroy_option, exec: false) - end - end end end diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 70627712092..72aa74ec40e 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -565,7 +565,7 @@ def user end describe "with allow destroy" do - shared_examples_for "has many persisted with allow_destroy = true" do |child_num| + shared_examples_for "has many with allow_destroy = true" do |child_num| it "should render the nested form" do expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][title]']") end @@ -583,7 +583,7 @@ def user end end - shared_examples_for "has many persisted with allow_destroy = false" do |child_num| + shared_examples_for "has many with allow_destroy = false" do |child_num| it "should render the nested form" do expect(body).to have_selector("input[name='category[posts_attributes][#{child_num}][title]']") end @@ -597,7 +597,7 @@ def user end end - shared_examples_for "has many persisted with allow_destroy as Symbol or Proc" do |allow_destroy_option| + shared_examples_for "has many with allow_destroy as String, Symbol or Proc" do |allow_destroy_option| let :body do s = self build_form({url: '/categories'}, Category.new) do |f| @@ -616,11 +616,11 @@ def user end context 'for the child that responds with true' do - it_behaves_like "has many persisted with allow_destroy = true", 0 + it_behaves_like "has many with allow_destroy = true", 0 end context 'for the child that responds with false' do - it_behaves_like "has many persisted with allow_destroy = false", 1 + it_behaves_like "has many with allow_destroy = false", 1 end end @@ -638,7 +638,7 @@ def user end end - it_behaves_like "has many persisted with allow_destroy = true", 0 + it_behaves_like "has many with allow_destroy = true", 0 end context "with allow_destroy = false" do @@ -654,7 +654,7 @@ def user end end - it_behaves_like "has many persisted with allow_destroy = false", 0 + it_behaves_like "has many with allow_destroy = false", 0 end context "with allow_destroy = nil" do @@ -670,29 +670,41 @@ def user end end - it_behaves_like "has many persisted with allow_destroy = false", 0 + it_behaves_like "has many with allow_destroy = false", 0 end context "with allow_destroy as Symbol" do - it_behaves_like("has many persisted with allow_destroy as Symbol or Proc", :foo?) + it_behaves_like("has many with allow_destroy as String, Symbol or Proc", :foo?) end context "with allow_destroy as String" do - it_behaves_like("has many persisted with allow_destroy as Symbol or Proc", "foo?") + it_behaves_like("has many with allow_destroy as String, Symbol or Proc", "foo?") end context "with allow_destroy as proc" do - it_behaves_like( - "has many persisted with allow_destroy as Symbol or Proc", - Proc.new { |child| child.foo? } - ) + it_behaves_like("has many with allow_destroy as String, Symbol or Proc", + Proc.new { |child| child.foo? }) end context "with allow_destroy as lambda" do - it_behaves_like( - "has many persisted with allow_destroy as Symbol or Proc", - -> (child) { child.foo? } - ) + it_behaves_like("has many with allow_destroy as String, Symbol or Proc", + -> (child) { child.foo? }) + end + + context "with allow_destroy as any other expression that evaluates to true" do + let :body do + s = self + build_form({url: '/categories'}, Category.new) do |f| + s.instance_exec do + allow(f.object.posts.build).to receive(:new_record?).and_return(false) + end + f.has_many :posts, allow_destroy: Object.new do |p| + p.input :title + end + end + end + + it_behaves_like "has many with allow_destroy = true", 0 end end @@ -707,7 +719,7 @@ def user end end - it_behaves_like "has many persisted with allow_destroy = false", 0 + it_behaves_like "has many with allow_destroy = false", 0 end end end From f28537766d5e3a900101afe42245b32d1c4d3a0d Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Sun, 21 Aug 2016 04:28:42 +0300 Subject: [PATCH 0172/3836] Make the has_many allow_destroy option smart When I generate nested has_many forms, I might whant to set the `allow_destroy` parameter depending on the child record. For example: I want to not allow delete comments, that was created by an admin, or I want to not allow delete articles that are published. I added the ability to specify Symbol and Proc as `allow_destroy` parameter. If a Symbol is specified, the child object's method will be called. # this will create 'delete' checkbox only for articles which #draft? method returns true f.has_many :articles, allow_destroy: :draft? do |a| If a Proc is specified, the given blok will be calculated for the child object. The object is passed as the parameter of the block. f.has_many :comments, allow_destroy: -> (comment) { !comment.author.admin? } do |c| --- spec/unit/form_builder_spec.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 72aa74ec40e..2624dda2bef 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -578,8 +578,11 @@ def user expect(body).to have_selector("label[for=category_posts_attributes_#{child_num}__destroy]", text: "Delete") end - it "should wrap the destroy field in an li with class 'has_many_delete'" do - expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1) + context "with allow_destroy as lambda" do + it_behaves_like( + "has many persisted with allow_destroy as Symbol or Proc", + -> (child) { child.foo? } + ) end end From e1e81575e95143a598e75ebf8e0c42ec8889f270 Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Tue, 23 Aug 2016 03:29:26 +0300 Subject: [PATCH 0173/3836] using existing helper methods --- spec/unit/form_builder_spec.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 2624dda2bef..72aa74ec40e 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -578,11 +578,8 @@ def user expect(body).to have_selector("label[for=category_posts_attributes_#{child_num}__destroy]", text: "Delete") end - context "with allow_destroy as lambda" do - it_behaves_like( - "has many persisted with allow_destroy as Symbol or Proc", - -> (child) { child.foo? } - ) + it "should wrap the destroy field in an li with class 'has_many_delete'" do + expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1) end end From 1aca52a04810b2a98c2f81e825eaf12a3e6644d7 Mon Sep 17 00:00:00 2001 From: Cody Robbins Date: Sun, 4 Sep 2016 20:04:38 -0400 Subject: [PATCH 0174/3836] Fixed a minor typo in the documentation for the columns component. --- lib/active_admin/views/components/columns.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/active_admin/views/components/columns.rb b/lib/active_admin/views/components/columns.rb index e1cf5cf0392..c2e298c55b5 100644 --- a/lib/active_admin/views/components/columns.rb +++ b/lib/active_admin/views/components/columns.rb @@ -14,7 +14,7 @@ module Views # # To create a two column layout: # - # colums do + # columns do # column do # span "Column # 1 # end @@ -28,7 +28,7 @@ module Views # # To make a column span multiple, pass the :span option to the column method: # - # colums do + # columns do # column span: 2 do # span "Column # 1 # end @@ -49,7 +49,7 @@ module Views # # To overcome this, columns include a :max_width and :min_width option. # - # colums do + # columns do # column max_width: "200px", min_width: "100px" do # span "Column # 1 # end From 5f2f194d5cbfe78a52fb427778ffa62f9d2285b4 Mon Sep 17 00:00:00 2001 From: Robert Dallas Gray Date: Mon, 12 Sep 2016 09:02:23 +0100 Subject: [PATCH 0175/3836] Pin tins and listen gems to make tests pass --- Gemfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index e7b5d9dc7a8..2eff1e6a212 100644 --- a/Gemfile +++ b/Gemfile @@ -58,11 +58,12 @@ group :test do gem 'capybara' gem 'simplecov', require: false # Test coverage generator. Go to /coverage/ after running tests gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io + gem 'tins', '~> 1.6.0', require: false # Required by coveralls, > 1.6.0 removes support for Ruby 1.9 gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' gem 'database_cleaner' gem 'guard-rspec', require: false - gem 'listen', '~> 2.7', platforms: :ruby_19 + gem 'listen', '~> 2.7', platforms: [:ruby_19, :jruby] gem 'jasmine' gem 'phantomjs', '1.9.8.0' # Same version as Travis CI's pre-installed version gem 'jslint_on_rails' From 01bcf34f0ee8ce438b51df56dc082da1d1d5203b Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Mon, 12 Sep 2016 18:24:43 +0300 Subject: [PATCH 0176/3836] change lambda syntax to work with ruby 1.9 --- spec/unit/form_builder_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 72aa74ec40e..90fee2c5cce 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -688,7 +688,7 @@ def user context "with allow_destroy as lambda" do it_behaves_like("has many with allow_destroy as String, Symbol or Proc", - -> (child) { child.foo? }) + lambda { |child| child.foo? }) end context "with allow_destroy as any other expression that evaluates to true" do From 654d0f459f02d4a3469501a3a42b35c16e57d880 Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Mon, 19 Sep 2016 17:21:51 +0300 Subject: [PATCH 0177/3836] Fix calling capybara matcher mistake --- spec/unit/form_builder_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 90fee2c5cce..f7adad3ba2a 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -545,7 +545,7 @@ def user end it "should add a custom header" do - expect(body).to have_selector("h3", "Test heading") + expect(body).to have_selector("h3", text: "Test heading") end end From 68d50d4221976df9d42e5d670b0877770ca8eeef Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Tue, 20 Sep 2016 01:07:31 +0300 Subject: [PATCH 0178/3836] Add has_many allow_destroy option description --- docs/5-forms.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/5-forms.md b/docs/5-forms.md index c16bc1aa7df..67bea6d86bd 100644 --- a/docs/5-forms.md +++ b/docs/5-forms.md @@ -96,7 +96,8 @@ ActiveAdmin.register Post do end end f.inputs do - f.has_many :comment, new_record: 'Leave Comment' do |b| + f.has_many :comment, new_record: 'Leave Comment', + allow_destroy: proc { |comment| comment.author?(current_admin_user) } do |b| b.input :body end end @@ -108,14 +109,14 @@ end The `:allow_destroy` option adds a checkbox to the end of the nested form allowing removal of the child object upon submission. Be sure to set `allow_destroy: true` -on the association to use this option. +on the association to use this option. It is possible to associate `:allow_destroy` with a string or a symbol, corresponding to the name of a child object's method that will get called, or with a Proc object. The Proc object receives the child object as a parameter and should return either true or false. The `:heading` option adds a custom heading. You can hide it entirely by passing `false`. The `:new_record` option controls the visibility of the new record button (shown by default). If you pass a string, it will be used as the text for the new record button. -The `:sortable` option adds a hidden field and will enable drag & drop sorting of the children. It +The `:sortable` option adds a hidden field and will enable drag & drop sorting of the children. It expects the name of the column that will store the index of each child. The `:sortable_start` option sets the value (0 by default) of the first position in the list. From f8926831429fe635d26ac8043ea5d676fb6ee637 Mon Sep 17 00:00:00 2001 From: Denis Talakevich Date: Tue, 20 Sep 2016 15:48:59 +0300 Subject: [PATCH 0179/3836] fix Filters::Humanized from wrong predicate detecting (#4509) --- lib/active_admin/filters/humanized.rb | 2 +- spec/unit/filters/humanized_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/filters/humanized.rb b/lib/active_admin/filters/humanized.rb index 3ff5e152273..d608c22f042 100644 --- a/lib/active_admin/filters/humanized.rb +++ b/lib/active_admin/filters/humanized.rb @@ -43,7 +43,7 @@ def parse_parameter_body end def current_predicate - @current_predicate ||= predicates.detect { |p| @body.include?(p) } + @current_predicate ||= predicates.detect { |p| @body.end_with?("_#{p}") } end def predicates diff --git a/spec/unit/filters/humanized_spec.rb b/spec/unit/filters/humanized_spec.rb index 5bf845e0aec..043656b92b3 100644 --- a/spec/unit/filters/humanized_spec.rb +++ b/spec/unit/filters/humanized_spec.rb @@ -52,5 +52,13 @@ expect(humanizer.body).to eq("Name Predicate Does Not Exist") end end + + context 'when column name similar to predicate' do + it 'parses correct predicate' do + param = ['time_start_gteq', 'test'] + humanizer = ActiveAdmin::Filters::Humanized.new(param) + expect(humanizer.body).to eq('Time Start greater than or equal to') + end + end end end From c65f86a444b92713560a6cf9d0148039b6774acb Mon Sep 17 00:00:00 2001 From: PqBenoit Date: Tue, 11 Oct 2016 21:57:25 -0400 Subject: [PATCH 0180/3836] Add number input type to modla dialog form (used for batch actions) --- app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee b/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee index 9ea767b639b..ae697ba61dd 100644 --- a/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee +++ b/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee @@ -1,7 +1,7 @@ ActiveAdmin.modal_dialog = (message, inputs, callback)-> html = """
      """ for name, type of inputs - if /^(datepicker|checkbox|text)$/.test type + if /^(datepicker|checkbox|text|number)$/.test type wrapper = 'input' else if type is 'textarea' wrapper = 'textarea' From 1317b7c361a6d7def0b1a4e8fad5d51b5a382214 Mon Sep 17 00:00:00 2001 From: Prasad Surase Date: Tue, 18 Oct 2016 11:38:59 +0530 Subject: [PATCH 0181/3836] Retrieved request via controller when checking unsupported browsers --- lib/active_admin/views/pages/base.rb | 2 +- spec/unit/views/components/unsupported_browser_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/active_admin/views/pages/base.rb b/lib/active_admin/views/pages/base.rb index 45b0ba0e549..1c796c829c4 100644 --- a/lib/active_admin/views/pages/base.rb +++ b/lib/active_admin/views/pages/base.rb @@ -56,7 +56,7 @@ def build_page end def build_unsupported_browser - if active_admin_namespace.unsupported_browser_matcher =~ request.user_agent + if active_admin_namespace.unsupported_browser_matcher =~ controller.request.user_agent insert_tag view_factory.unsupported_browser end end diff --git a/spec/unit/views/components/unsupported_browser_spec.rb b/spec/unit/views/components/unsupported_browser_spec.rb index 2c16ba22959..1af3c129d2d 100644 --- a/spec/unit/views/components/unsupported_browser_spec.rb +++ b/spec/unit/views/components/unsupported_browser_spec.rb @@ -22,7 +22,7 @@ def build_panel context "when the reqex match" do it "should build the unsupported browser panel" do expect(base).to receive(:active_admin_namespace).and_return(namespace) - expect(base).to receive_message_chain(:request, :user_agent).and_return("Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0)") + expect(base).to receive_message_chain(:controller, :request, :user_agent).and_return("Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0)") expect(base).to receive(:view_factory).and_return(view_factory) expect(base).to receive(:insert_tag).with(component) base.send(:build_unsupported_browser) @@ -32,7 +32,7 @@ def build_panel context "when the regex not match" do it "should not build the unsupported browser panel" do expect(base).to receive(:active_admin_namespace).and_return(namespace) - expect(base).to receive_message_chain(:request, :user_agent).and_return("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)") + expect(base).to receive_message_chain(:controller, :request, :user_agent).and_return("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)") expect(base).to receive(:insert_tag).never base.send(:build_unsupported_browser) end From e6c4966fa253685953f1888589968ec6b3ad6d1f Mon Sep 17 00:00:00 2001 From: Ward van Teijlingen Date: Tue, 29 Nov 2016 14:18:17 +0100 Subject: [PATCH 0182/3836] Lock jquery-ui-rails dependency to '~> 5.0' --- activeadmin.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index e20184d74ee..848e5d71cc3 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |s| s.add_dependency 'formtastic_i18n' s.add_dependency 'inherited_resources', '~> 1.6' s.add_dependency 'jquery-rails' - s.add_dependency 'jquery-ui-rails' + s.add_dependency 'jquery-ui-rails', '~> 5.0' s.add_dependency 'kaminari', '~> 0.15' s.add_dependency 'railties', '>= 3.2', '< 5.1' s.add_dependency 'ransack', '~> 1.3' From 5b8ded8bcc1cd3ed09ea5c10fc992e47614d4bd1 Mon Sep 17 00:00:00 2001 From: Oleg Grigoriev Date: Tue, 29 Nov 2016 23:29:18 +0300 Subject: [PATCH 0183/3836] correct assets paths for jquery-ui-rails v6, fix https://github.com/activeadmin/activeadmin/issues/4672 --- .../javascripts/active_admin/jquery_ui.js.erb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/active_admin/jquery_ui.js.erb b/app/assets/javascripts/active_admin/jquery_ui.js.erb index c40b276b7f2..624631bf805 100644 --- a/app/assets/javascripts/active_admin/jquery_ui.js.erb +++ b/app/assets/javascripts/active_admin/jquery_ui.js.erb @@ -4,8 +4,15 @@ "jquery.ui." end %> -<% require_asset "#{jquery_ui_path}datepicker" %> -<% require_asset "#{jquery_ui_path}dialog" %> -<% require_asset "#{jquery_ui_path}sortable" %> +<% jquery_ui_widgets_path = + if Jquery::Ui::Rails::VERSION >= "6" + jquery_ui_path + "widgets/" + else + jquery_ui_path + end +%> +<% require_asset "#{jquery_ui_widgets_path}datepicker" %> +<% require_asset "#{jquery_ui_widgets_path}dialog" %> +<% require_asset "#{jquery_ui_widgets_path}sortable" %> +<% require_asset "#{jquery_ui_widgets_path}tabs" %> <% require_asset "#{jquery_ui_path}widget" %> -<% require_asset "#{jquery_ui_path}tabs" %> From b89379dc22e5e84eb5998d609e10cd921d9c307f Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Wed, 30 Nov 2016 00:06:47 +0100 Subject: [PATCH 0184/3836] Revert "Lock jquery-ui-rails dependency to '~> 5.0'" --- activeadmin.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index 848e5d71cc3..e20184d74ee 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |s| s.add_dependency 'formtastic_i18n' s.add_dependency 'inherited_resources', '~> 1.6' s.add_dependency 'jquery-rails' - s.add_dependency 'jquery-ui-rails', '~> 5.0' + s.add_dependency 'jquery-ui-rails' s.add_dependency 'kaminari', '~> 0.15' s.add_dependency 'railties', '>= 3.2', '< 5.1' s.add_dependency 'ransack', '~> 1.3' From 62c5e2895150d7ecdb92da6be5a89e57d005e98e Mon Sep 17 00:00:00 2001 From: Vijay Raghavan Aravamudhan Date: Tue, 6 Dec 2016 13:17:09 +0530 Subject: [PATCH 0185/3836] #4687 Wrap the action link text with spans that can be styled using CSS to replace ther content with images/icons for better horizontal screenspace. --- lib/active_admin/views/index_as_table.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/active_admin/views/index_as_table.rb b/lib/active_admin/views/index_as_table.rb index 0e32338b3b0..cc8fdfa823e 100644 --- a/lib/active_admin/views/index_as_table.rb +++ b/lib/active_admin/views/index_as_table.rb @@ -348,13 +348,13 @@ def actions(options = {}, &block) def defaults(resource, options = {}) if controller.action_methods.include?('show') && authorized?(ActiveAdmin::Auth::READ, resource) - item I18n.t('active_admin.view'), resource_path(resource), class: "view_link #{options[:css_class]}" + item I18n.t('active_admin.view'), resource_path(resource), class: "view_link #{options[:css_class]}", title: I18n.t('active_admin.view') end if controller.action_methods.include?('edit') && authorized?(ActiveAdmin::Auth::UPDATE, resource) - item I18n.t('active_admin.edit'), edit_resource_path(resource), class: "edit_link #{options[:css_class]}" + item I18n.t('active_admin.edit'), edit_resource_path(resource), class: "edit_link #{options[:css_class]}", title: I18n.t('active_admin.edit') end if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource) - item I18n.t('active_admin.delete'), resource_path(resource), class: "delete_link #{options[:css_class]}", + item I18n.t('active_admin.delete'), resource_path(resource), class: "delete_link #{options[:css_class]}", title: I18n.t('active_admin.delete'), method: :delete, data: {confirm: I18n.t('active_admin.delete_confirmation')} end end From e5d87cab17045289f0d612f1db97f296f2a66823 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Wed, 28 Dec 2016 14:09:37 -0500 Subject: [PATCH 0186/3836] Alter published_at:datetime to published_date:date --- features/development_reloading.feature | 2 +- features/edit_page.feature | 12 ++++++------ features/index/filters.feature | 14 +++++++------- features/index/format_as_csv.feature | 4 ++-- features/index/index_as_table.feature | 12 ++++++------ features/index/index_scope_to.feature | 2 +- features/index/index_scopes.feature | 6 +++--- features/new_page.feature | 12 ++++++------ features/renamed_resource.feature | 2 +- features/step_definitions/factory_steps.rb | 2 +- spec/support/rails_template.rb | 8 ++++---- spec/support/rails_template_with_data.rb | 12 ++++++------ spec/unit/csv_builder_spec.rb | 8 ++++---- spec/unit/filters/resource_spec.rb | 6 +++--- spec/unit/form_builder_spec.rb | 10 +++++----- 15 files changed, 56 insertions(+), 56 deletions(-) diff --git a/features/development_reloading.feature b/features/development_reloading.feature index cc087784a15..431c8de419f 100644 --- a/features/development_reloading.feature +++ b/features/development_reloading.feature @@ -14,7 +14,7 @@ Feature: Development Reloading ActiveAdmin.register Post do if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, - :body, :position, :published_at, :starred + :body, :position, :published_date, :starred end end """ diff --git a/features/edit_page.feature b/features/edit_page.feature index 1cb73a22e7f..8198060f9e3 100644 --- a/features/edit_page.feature +++ b/features/edit_page.feature @@ -12,7 +12,7 @@ Feature: Edit Page ActiveAdmin.register Post do if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, - :body, :position, :published_at, :starred + :body, :position, :published_date, :starred end end """ @@ -34,7 +34,7 @@ Feature: Edit Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 + permit_params :category, :author, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 form do |f| f.inputs "Your Post" do @@ -42,7 +42,7 @@ Feature: Edit Page f.input :body end f.inputs "Publishing" do - f.input :published_at + f.input :published_date end f.actions end @@ -63,7 +63,7 @@ Feature: Edit Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 + permit_params :category, :author, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 form :html => {} do |f| f.inputs "Your Post" do @@ -71,7 +71,7 @@ Feature: Edit Page f.input :body end f.inputs "Publishing" do - f.input :published_at + f.input :published_date end f.actions end @@ -102,7 +102,7 @@ Feature: Edit Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :category, :author, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 + permit_params :category, :author, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 form :partial => "form" end diff --git a/features/index/filters.feature b/features/index/filters.feature index 3c80f0bebf2..3a1daac910a 100644 --- a/features/index/filters.feature +++ b/features/index/filters.feature @@ -9,13 +9,13 @@ Feature: Index Filtering When I am on the index page for posts Then I should see "Displaying all 3 Posts" And I should see the following filters: - | Author | select | - | Category | select | - | Title | string | - | Body | string | - | Published at | date range | - | Created at | date range | - | Updated at | date range | + | Author | select | + | Category | select | + | Title | string | + | Body | string | + | Published date | date range | + | Created at | date range | + | Updated at | date range | When I fill in "Title" with "Hello World 2" And I press "Filter" diff --git a/features/index/format_as_csv.feature b/features/index/format_as_csv.feature index cf18a42bba9..1f082a0e9bc 100644 --- a/features/index/format_as_csv.feature +++ b/features/index/format_as_csv.feature @@ -12,7 +12,7 @@ Feature: Format as CSV When I am on the index page for posts And I follow "CSV" And I should download a CSV file for "posts" containing: - | Id | Title | Body | Published at | Position | Starred | Created at | Updated at | + | Id | Title | Body | Published date | Position | Starred | Created at | Updated at | | \d+ | Hello World | | | | | (.*) | (.*) | Scenario: Default with alias @@ -24,7 +24,7 @@ Feature: Format as CSV When I am on the index page for my_articles And I follow "CSV" And I should download a CSV file for "my-articles" containing: - | Id | Title | Body | Published at | Position | Starred | Created at | Updated at | + | Id | Title | Body | Published date | Position | Starred | Created at | Updated at | Scenario: With CSV format customization Given a configuration of: diff --git a/features/index/index_as_table.feature b/features/index/index_as_table.feature index 8aeab738590..7eb8c62c741 100644 --- a/features/index/index_as_table.feature +++ b/features/index/index_as_table.feature @@ -218,13 +218,13 @@ Feature: Index as Table ActiveAdmin.register Post do index do column :author_id do end - column 'published_at' do end + column 'published_date' do end column :category do end end end """ Then I should see a sortable table header with "Author" - Then I should see a sortable table header with "published_at" + Then I should see a sortable table header with "published_date" Then I should not see a sortable table header with "Category" Scenario: Columns with block are not sortable by when sortable option equals to false @@ -234,12 +234,12 @@ Feature: Index as Table ActiveAdmin.register Post do index do column :author_id, sortable: false do end - column 'published_at', sortable: false do end + column 'published_date', sortable: false do end end end """ Then I should not see a sortable table header with "Author" - Then I should not see a sortable table header with "published_at" + Then I should not see a sortable table header with "published_date" Scenario: Sorting Given a post with the title "Hello World" and body "From the body" exists @@ -250,12 +250,12 @@ Feature: Index as Table """ When I am on the index page for posts Then I should see the "index_table_posts" table: - | [ ] | Id | Title | Body | Published At | Position | Starred | Created At | Updated At | | + | [ ] | Id | Title | Body | Published Date | Position | Starred | Created At | Updated At | | | [ ] | 2 | Bye bye world | Move your... | | | No | /.*/ | /.*/ | ViewEditDelete | | [ ] | 1 | Hello World | From the body | | | No | /.*/ | /.*/ | ViewEditDelete | When I follow "Id" Then I should see the "index_table_posts" table: - | [ ] | Id | Title | Body | Published At | Position | Starred | Created At | Updated At | | + | [ ] | Id | Title | Body | Published Date | Position | Starred | Created At | Updated At | | | [ ] | 1 | Hello World | From the body | | | No | /.*/ | /.*/ | ViewEditDelete | | [ ] | 2 | Bye bye world | Move your... | | | No | /.*/ | /.*/ | ViewEditDelete | diff --git a/features/index/index_scope_to.feature b/features/index/index_scope_to.feature index cdb7c87de55..d3f2876998e 100644 --- a/features/index/index_scope_to.feature +++ b/features/index/index_scope_to.feature @@ -17,7 +17,7 @@ Feature: Index Scope To # Set up some scopes scope :all, default: true scope :published do |posts| - posts.where "published_at IS NOT NULL" + posts.where "published_date IS NOT NULL" end end """ diff --git a/features/index/index_scopes.feature b/features/index/index_scopes.feature index b3af40c1f36..817a48ee24b 100644 --- a/features/index/index_scopes.feature +++ b/features/index/index_scopes.feature @@ -85,7 +85,7 @@ Feature: Index Scoping ActiveAdmin.register Post do scope :all, :default => true scope :published do |posts| - posts.where("published_at IS NOT NULL") + posts.where("published_date IS NOT NULL") end end """ @@ -108,7 +108,7 @@ Feature: Index Scoping ActiveAdmin.register Post do scope :all, :default => true scope :published do |posts| - posts.where("published_at IS NOT NULL") + posts.where("published_date IS NOT NULL") end end """ @@ -215,7 +215,7 @@ Feature: Index Scoping ActiveAdmin.register Post do scope :all, :default => true scope :published do |posts| - posts.where("published_at IS NOT NULL") + posts.where("published_date IS NOT NULL") end index do diff --git a/features/new_page.feature b/features/new_page.feature index a10a384405e..57223e9114c 100644 --- a/features/new_page.feature +++ b/features/new_page.feature @@ -11,7 +11,7 @@ Feature: New Page ActiveAdmin.register Post do if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, - :body, :position, :published_at, :starred + :body, :position, :published_date, :starred end end """ @@ -34,7 +34,7 @@ Feature: New Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 + permit_params :custom_category_id, :author_id, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 form do |f| f.inputs "Your Post" do @@ -42,7 +42,7 @@ Feature: New Page f.input :body end f.inputs "Publishing" do - f.input :published_at + f.input :published_date end f.actions end @@ -70,7 +70,7 @@ Feature: New Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 + permit_params :custom_category_id, :author_id, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 form :partial => "form" end @@ -87,7 +87,7 @@ Feature: New Page Given a configuration of: """ ActiveAdmin.register Post do - permit_params :custom_category_id, :author_id, :title, :body, :published_at, :starred if Rails::VERSION::MAJOR >= 4 + permit_params :custom_category_id, :author_id, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 form do |f| f.inputs "Your Post" do @@ -98,7 +98,7 @@ Feature: New Page f.input :body end f.inputs "Publishing" do - f.input :published_at + f.input :published_date end f.actions end diff --git a/features/renamed_resource.feature b/features/renamed_resource.feature index e6fa6ff7b48..886db9f6add 100644 --- a/features/renamed_resource.feature +++ b/features/renamed_resource.feature @@ -11,7 +11,7 @@ Feature: Renamed Resource ActiveAdmin.register Blog::Post, as: 'Post' do if Rails::VERSION::MAJOR >= 4 permit_params :custom_category_id, :author_id, :title, - :body, :position, :published_at, :starred + :body, :position, :published_date, :starred end end """ diff --git a/features/step_definitions/factory_steps.rb b/features/step_definitions/factory_steps.rb index 5375eabe705..c07d2c1db7d 100644 --- a/features/step_definitions/factory_steps.rb +++ b/features/step_definitions/factory_steps.rb @@ -11,7 +11,7 @@ def create_user(name, type = 'User') category = Category.where(name: category_name).first_or_create if category_name title ||= "Hello World %i" count.times do |i| - Post.create! title: title % i, body: body, author: author, published_at: published, custom_category_id: category.try(:id), starred: starred + Post.create! title: title % i, body: body, author: author, published_date: published, custom_category_id: category.try(:id), starred: starred end end diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index fc4efd4d496..d0ab8f9204f 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -4,7 +4,7 @@ copy_file File.expand_path('../templates/manifest.js', __FILE__), 'app/assets/config/manifest.js', force: true end -generate :model, 'post title:string body:text published_at:datetime author_id:integer ' + +generate :model, 'post title:string body:text published_date:date author_id:integer ' + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' create_file 'app/models/post.rb', <<-RUBY.strip_heredoc, force: true class Post < ActiveRecord::Base @@ -15,13 +15,13 @@ class Post < ActiveRecord::Base accepts_nested_attributes_for :taggings unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes - attr_accessible :id, :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id, :category + attr_accessible :id, :title, :body, :starred, :author, :position, :published_date, :author_id, :custom_category_id, :category end end RUBY copy_file File.expand_path('../templates/post_decorator.rb', __FILE__), 'app/models/post_decorator.rb' -generate :model, 'blog/post title:string body:text published_at:datetime author_id:integer ' + +generate :model, 'blog/post title:string body:text published_date:date author_id:integer ' + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' create_file 'app/models/blog/post.rb', <<-RUBY.strip_heredoc, force: true class Blog::Post < ActiveRecord::Base @@ -32,7 +32,7 @@ class Blog::Post < ActiveRecord::Base accepts_nested_attributes_for :taggings unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes - attr_accessible :title, :body, :starred, :author, :position, :published_at, :author_id, :custom_category_id, :category + attr_accessible :title, :body, :starred, :author, :position, :published_date, :author_id, :custom_category_id, :category end end RUBY diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 7c00022c8fa..033096c7d86 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -21,21 +21,21 @@ inject_into_file 'app/admin/post.rb', <<-RUBY, after: "ActiveAdmin.register Post do\n" if Rails::VERSION::MAJOR >= 4 - permit_params [:custom_category_id, :author_id, :title, :body, :published_at, :position, :starred] + permit_params [:custom_category_id, :author_id, :title, :body, :published_date, :position, :starred] end scope :all, default: true scope :drafts do |posts| - posts.where(["published_at IS NULL"]) + posts.where(["published_date IS NULL"]) end scope :scheduled do |posts| - posts.where(["posts.published_at IS NOT NULL AND posts.published_at > ?", Time.now.utc]) + posts.where(["posts.published_date IS NOT NULL AND posts.published_date > ?", Time.now.utc]) end scope :published do |posts| - posts.where(["posts.published_at IS NOT NULL AND posts.published_at < ?", Time.now.utc]) + posts.where(["posts.published_date IS NOT NULL AND posts.published_date < ?", Time.now.utc]) end scope :my_posts do |posts| @@ -61,11 +61,11 @@ 1_000.times do |i| user = users[i % users.size] cat = categories[i % categories.size] - published_at = published_at_values[i % published_at_values.size] + published = published_at_values[i % published_at_values.size] Post.create title: "Blog Post \#{i}", body: "Blog post \#{i} is written by \#{user.username} about \#{cat.name}", category: cat, - published_at: published_at, + published_date: published, author: user, starred: true end diff --git a/spec/unit/csv_builder_spec.rb b/spec/unit/csv_builder_spec.rb index d20a3646214..f554e888dd1 100644 --- a/spec/unit/csv_builder_spec.rb +++ b/spec/unit/csv_builder_spec.rb @@ -189,8 +189,8 @@ context "build csv using the supplied order" do before do - @post1 = Post.create!(title: "Hello1", published_at: Date.today - 2.day ) - @post2 = Post.create!(title: "Hello2", published_at: Date.today - 1.day ) + @post1 = Post.create!(title: "Hello1", published_date: Date.today - 2.day ) + @post2 = Post.create!(title: "Hello2", published_date: Date.today - 1.day ) end let(:dummy_controller) { class DummyController @@ -199,7 +199,7 @@ def find_collection(*) end def collection - Post.order('published_at DESC') + Post.order('published_date DESC') end def apply_decorator(resource) @@ -215,7 +215,7 @@ def view_context ActiveAdmin::CSVBuilder.new do column "id" column "title" - column "published_at" + column "published_date" end end diff --git a/spec/unit/filters/resource_spec.rb b/spec/unit/filters/resource_spec.rb index cd3819f1bde..6c4b6335942 100644 --- a/spec/unit/filters/resource_spec.rb +++ b/spec/unit/filters/resource_spec.rb @@ -13,7 +13,7 @@ it "should return the defaults if no filters are set" do expect(resource.filters.keys).to match_array([ - :author, :body, :category, :created_at, :custom_searcher, :position, :published_at, :starred, :taggings, :title, :updated_at + :author, :body, :category, :created_at, :custom_searcher, :position, :published_date, :starred, :taggings, :title, :updated_at ]) end @@ -35,7 +35,7 @@ it "should return the defaults without associations if default association filters are disabled on the namespace" do resource.namespace.include_default_association_filters = false expect(resource.filters.keys).to match_array([ - :body, :created_at, :custom_searcher, :position, :published_at, :starred, :title, :updated_at + :body, :created_at, :custom_searcher, :position, :published_date, :starred, :title, :updated_at ]) end @@ -104,7 +104,7 @@ resource.add_filter :count, as: :string expect(resource.filters.keys).to match_array([ - :author, :body, :category, :count, :created_at, :custom_searcher, :position, :published_at, :starred, :taggings, :title, :updated_at + :author, :body, :category, :count, :created_at, :custom_searcher, :position, :published_date, :starred, :taggings, :title, :updated_at ]) end diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index f7adad3ba2a..2718d3da456 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -409,7 +409,7 @@ def user end f.inputs do f.input :author - f.input :published_at + f.input :created_at end end end @@ -417,10 +417,10 @@ def user expect(body).to have_selector("input[name='post[title]']", count: 1) expect(body).to have_selector("textarea[name='post[body]']", count: 1) expect(body).to have_selector("select[name='post[author_id]']", count: 1) - expect(body).to have_selector("select[name='post[published_at(1i)]']", count: 1) - expect(body).to have_selector("select[name='post[published_at(2i)]']", count: 1) - expect(body).to have_selector("select[name='post[published_at(3i)]']", count: 1) - expect(body).to have_selector("select[name='post[published_at(4i)]']", count: 1) + expect(body).to have_selector("select[name='post[created_at(1i)]']", count: 1) + expect(body).to have_selector("select[name='post[created_at(2i)]']", count: 1) + expect(body).to have_selector("select[name='post[created_at(3i)]']", count: 1) + expect(body).to have_selector("select[name='post[created_at(4i)]']", count: 1) end end From 9c3db9f486623962ee4e85cd15bf4ea0f2b4e896 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Wed, 28 Dec 2016 14:10:33 -0500 Subject: [PATCH 0187/3836] Use custom ransacker predicates for datetime, not date. --- .../inputs/filters/date_range_input.rb | 4 ++-- lib/ransack_ext.rb | 4 ++-- spec/unit/filters/filter_form_builder_spec.rb | 18 ++++++++++++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/active_admin/inputs/filters/date_range_input.rb b/lib/active_admin/inputs/filters/date_range_input.rb index 11821351c73..d75df1a2a12 100644 --- a/lib/active_admin/inputs/filters/date_range_input.rb +++ b/lib/active_admin/inputs/filters/date_range_input.rb @@ -15,12 +15,12 @@ def to_html end def gt_input_name - "#{method}_gteq_date" + column && column.type == :date ? "#{method}_gteq" : "#{method}_gteq_datetime" end alias :input_name :gt_input_name def lt_input_name - "#{method}_lteq_date" + column && column.type == :date ? "#{method}_lteq" : "#{method}_lteq_datetime" end def input_html_options(input_name = gt_input_name) diff --git a/lib/ransack_ext.rb b/lib/ransack_ext.rb index a4e2c66ca62..9530188b41c 100644 --- a/lib/ransack_ext.rb +++ b/lib/ransack_ext.rb @@ -10,11 +10,11 @@ config.add_predicate old, arel_predicate: current end - config.add_predicate 'gteq_date', + config.add_predicate 'gteq_datetime', arel_predicate: 'gteq', formatter: ->(v) { v.beginning_of_day } - config.add_predicate 'lteq_date', + config.add_predicate 'lteq_datetime', arel_predicate: 'lt', formatter: ->(v) { v + 1.day } end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 17c8aeca974..cb8890bb88d 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -153,17 +153,31 @@ def filter(name, options = {}) end end + describe "date attribute" do + let(:body) { Capybara.string(filter :published_date) } + + it "should generate a date greater than" do + expect(body).to have_selector("input.datepicker[name='q[published_date_gteq]']") + end + it "should generate a seperator" do + expect(body).to have_selector("span.seperator") + end + it "should generate a date less than" do + expect(body).to have_selector("input.datepicker[name='q[published_date_lteq]']") + end + end + describe "datetime attribute" do let(:body) { Capybara.string(filter :created_at) } it "should generate a date greater than" do - expect(body).to have_selector("input.datepicker[name='q[created_at_gteq_date]']") + expect(body).to have_selector("input.datepicker[name='q[created_at_gteq_datetime]']") end it "should generate a seperator" do expect(body).to have_selector("span.seperator") end it "should generate a date less than" do - expect(body).to have_selector("input.datepicker[name='q[created_at_lteq_date]']") + expect(body).to have_selector("input.datepicker[name='q[created_at_lteq_datetime]']") end end From d5638b33841cd6b0987f9086c7cd4e2b10982b88 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 4 Jan 2017 19:28:44 +0200 Subject: [PATCH 0188/3836] fix dependencies for ruby 1.9.3 --- Gemfile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 2eff1e6a212..45d8339e841 100644 --- a/Gemfile +++ b/Gemfile @@ -20,7 +20,13 @@ if rails_major == '5' gem 'ransack', github: 'activerecord-hackery/ransack' end -gem 'mime-types', '< 3' # Remove this line when we drop support for Ruby 1.9 +platform :ruby_19 do # Remove this block when we drop support for Ruby 1.9 + gem 'mime-types', '< 3' + gem 'nokogiri', '< 1.7' + gem 'public_suffix', '< 1.5' + gem 'term-ansicolor', '< 1.4' +end + # Optional dependencies gem 'cancan' @@ -30,7 +36,7 @@ gem 'pundit' # Utility gems used in both development & test environments gem 'rake', require: false -gem 'parallel_tests' +gem 'parallel_tests', '< 2.10' #2.10 requires ruby '>= 2.0.0' # Debugging gem 'pry' # Easily debug from your console with `binding.pry` From 72e1cab913cb7e0658f2205829f2aab77456ec31 Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 4 Jan 2017 20:47:46 -0300 Subject: [PATCH 0189/3836] Added styles for input[type="time"] --- app/assets/stylesheets/active_admin/_forms.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/active_admin/_forms.scss b/app/assets/stylesheets/active_admin/_forms.scss index 93832db678c..ab93bbab99d 100644 --- a/app/assets/stylesheets/active_admin/_forms.scss +++ b/app/assets/stylesheets/active_admin/_forms.scss @@ -125,6 +125,7 @@ form { input[type=url], input[type=tel], input[type=date], + input[type=time], textarea { width: calc(80% - #{$text-input-total-padding}); border: $border-width solid #c9d0d6; From 031c0b15f2eedafdae697295b064efb04480ee61 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 28 Dec 2016 13:33:56 +0200 Subject: [PATCH 0190/3836] fixed form behaviour when using has_many with inputs block --- lib/active_admin/form_builder.rb | 6 ++++-- spec/support/rails_template.rb | 4 ++++ spec/unit/form_builder_spec.rb | 30 ++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/form_builder.rb b/lib/active_admin/form_builder.rb index 911f4e04384..8c98476e66b 100644 --- a/lib/active_admin/form_builder.rb +++ b/lib/active_admin/form_builder.rb @@ -55,10 +55,12 @@ def has_many(assoc, options = {}, &block) end html << template.capture do - contents = "".html_safe form_block = proc do |has_many_form| index = parent_child_index options[:parent] if options[:parent] - block.call has_many_form, index + block_contents = template.capture do + block.call(has_many_form, index) + end + template.concat(block_contents) template.concat has_many_actions(has_many_form, builder_options, "".html_safe) end diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index fc4efd4d496..bcae88b593b 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -59,6 +59,10 @@ def display_name create_file 'app/models/profile.rb', <<-RUBY.strip_heredoc, force: true class Profile < ActiveRecord::Base belongs_to :user + + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes + attr_accessible :bio + end end RUBY diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index f7adad3ba2a..5b9b6458ab9 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -284,6 +284,36 @@ def build_form(options = {}, form_object = Post.new, &block) end + context "with inputs component inside has_many" do + + def user + u = User.new + u.profile = Profile.new(bio: 'bio') + u + end + + let :body do + author = user() + build_form do |f| + f.form_builder.instance_eval do + @object.author = author + end + f.inputs name: 'Author', for: :author do |author| + author.has_many :profile, allow_destroy: true do |profile| + profile.inputs "inputs for profile #{profile.object.bio}" do + profile.input :bio + end + end + end + end + end + + it "should see the profile fields for an existing profile" do + expect(body).to have_selector("[id='post_author_attributes_profile_attributes_bio']", count: 1) + expect(body).to have_selector("textarea[name='post[author_attributes][profile_attributes][bio]']") + end + end + context "with a has_one relation on an author's profile" do let :body do author = user() From 209331f197996c0d09254a4c31f20ddfdf9e02fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Sep 2016 12:19:52 -0300 Subject: [PATCH 0191/3836] Test against latest versions of things --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc45faba655..9ec30576436 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,24 +11,24 @@ install: script: - bundle exec rake test_with_coveralls rvm: - - 1.9 - - 2.3.0 - - jruby-9.0.5.0 + - 1.9.3 + - 2.3.3 + - jruby-9.1.6.0 env: matrix: - RAILS=3.2.22 - - RAILS=4.2.5 - - RAILS=5.0.0 + - RAILS=4.2.7.1 + - RAILS=5.0.1 global: - JRUBY_OPTS="-J-Xmx1024m --debug" matrix: fast_finish: true exclude: - - rvm: 1.9 - env: RAILS=5.0.0 + - rvm: 1.9.3 + env: RAILS=5.0.1 allow_failures: - - rvm: jruby-9.0.5.0 - env: RAILS=5.0.0 + - rvm: jruby-9.1.6.0 + env: RAILS=5.0.1 notifications: irc: channels: From e79de33d3a13b22631b722da00d07ab11047c55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 11 Sep 2016 18:12:43 -0300 Subject: [PATCH 0192/3836] Include all oficial rubies in Travis matrix --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9ec30576436..936db4b0aca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ script: - bundle exec rake test_with_coveralls rvm: - 1.9.3 + - 2.2.6 - 2.3.3 - jruby-9.1.6.0 env: From 39c61047bfd3f81b903fa5a48fe1e84f0e6c4305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 12 Sep 2016 04:12:38 -0300 Subject: [PATCH 0193/3836] Bring back Rails 4.0/4.1 + Ruby 1.9.3 support --- lib/active_admin/batch_actions/resource_extension.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/batch_actions/resource_extension.rb b/lib/active_admin/batch_actions/resource_extension.rb index 4f3bf3607e7..31f606e09d4 100644 --- a/lib/active_admin/batch_actions/resource_extension.rb +++ b/lib/active_admin/batch_actions/resource_extension.rb @@ -55,7 +55,8 @@ def clear_batch_actions! def batch_action_path(params = {}) path = [route_collection_path(params), "batch_action"].join("/") query = params.slice(:q, :scope) - query = query.permit!.to_h if query.respond_to? :permit! + query = query.permit! if query.respond_to? :permit! + query = query.to_h if Rails::VERSION::MAJOR >= 5 [path, query.to_param].reject(&:blank?).join("?") end From 6cd714dd1200ef2f9bdfdf0f7cf1ceb4b3b0a9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 13 Sep 2016 17:56:03 -0300 Subject: [PATCH 0194/3836] Use latest Rubygems Travis with such a big matrix like ours is very likely to expose bugs in Rubygems and Bundler. By using the latest versions, we make sure we always get the latest bug fixes from upstream. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 936db4b0aca..ce58f1ad465 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: ruby sudo: false install: - ./script/travis_cache download_bundle + - gem update --system # use the very latest Rubygems - gem install bundler # use the very latest Bundler - bundle install --without development --path=./bundle - bundle clean # delete now-outdated gems From 3ffa3cd5ded591bdf67eb8831f4cddaa1263da8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 12 Sep 2016 03:17:19 -0300 Subject: [PATCH 0195/3836] Fix 1.9.3 dependency constraints Otherwise installing deps for the 1.9.3 + Rails 4.0 combo fails with ``` json-2.0.2 requires ruby version ~> 2.0, which is incompatible with the current version, ruby 1.9.3p551 ``` --- Gemfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 45d8339e841..c8ac72d0a7c 100644 --- a/Gemfile +++ b/Gemfile @@ -43,7 +43,9 @@ gem 'pry' # Easily debug from your console wit group :development do # Debugging - gem 'better_errors' # Web UI to debug exceptions. Go to /__better_errors to access the latest one + gem 'better_errors', # Web UI to debug exceptions. Go to /__better_errors to access the latest one + platforms: [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem 'binding_of_caller', platforms: :mri # Retrieve the binding of a method's caller in MRI Ruby >= 1.9.2 # Performance @@ -63,6 +65,7 @@ end group :test do gem 'capybara' gem 'simplecov', require: false # Test coverage generator. Go to /coverage/ after running tests + gem 'json', '~> 1.8', require: false # Required by simplecov, > 2 removes support for Ruby 1.9 gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io gem 'tins', '~> 1.6.0', require: false # Required by coveralls, > 1.6.0 removes support for Ruby 1.9 gem 'cucumber-rails', require: false From 81bcae3525f315e0d5e5049b6de8651475fba234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 9 Jan 2017 08:32:39 -0200 Subject: [PATCH 0196/3836] Restore Rails 4.0 and 4.1 entries in Travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index ce58f1ad465..110a809b24d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,8 @@ rvm: env: matrix: - RAILS=3.2.22 + - RAILS=4.0.13 + - RAILS=4.1.16 - RAILS=4.2.7.1 - RAILS=5.0.1 global: From 5d5e881f835f6d3beb423a2014f7fd2afa0c2efa Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Tue, 10 Jan 2017 12:47:49 -0500 Subject: [PATCH 0197/3836] Switch from Coveralls to Codecov. --- .travis.yml | 2 +- Gemfile | 4 +--- README.md | 2 +- spec/spec_helper.rb | 3 +++ tasks/test.rake | 4 ---- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc45faba655..536a3060d5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ install: - bundle exec rake setup - ./script/travis_cache upload script: - - bundle exec rake test_with_coveralls + - bundle exec rake test rvm: - 1.9 - 2.3.0 diff --git a/Gemfile b/Gemfile index 45d8339e841..07a5c7826e8 100644 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,6 @@ platform :ruby_19 do # Remove this block when we drop support for Ruby 1.9 gem 'mime-types', '< 3' gem 'nokogiri', '< 1.7' gem 'public_suffix', '< 1.5' - gem 'term-ansicolor', '< 1.4' end @@ -63,8 +62,7 @@ end group :test do gem 'capybara' gem 'simplecov', require: false # Test coverage generator. Go to /coverage/ after running tests - gem 'coveralls', require: false # Test coverage website. Go to https://coveralls.io - gem 'tins', '~> 1.6.0', require: false # Required by coveralls, > 1.6.0 removes support for Ruby 1.9 + gem 'codecov', require: false # Test coverage website. Go to https://codecov.io gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' gem 'database_cleaner' diff --git a/README.md b/README.md index c0fd4d8d86e..59b15401d79 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Active Admin is a Ruby on Rails framework for creating elegant backends for webs [![Version ](http://img.shields.io/gem/v/activeadmin.svg) ](https://rubygems.org/gems/activeadmin) [![Travis CI ](http://img.shields.io/travis/activeadmin/activeadmin/master.svg) ](https://travis-ci.org/activeadmin/activeadmin) [![Quality ](http://img.shields.io/codeclimate/github/activeadmin/activeadmin.svg) ](https://codeclimate.com/github/activeadmin/activeadmin) -[![Coverage ](http://img.shields.io/coveralls/activeadmin/activeadmin.svg) ](https://coveralls.io/r/activeadmin/activeadmin) +[![Coverage ](https://codecov.io/gh/activeadmin/activeadmin/branch/master/graph/badge.svg)](https://codecov.io/gh/activeadmin/activeadmin) [![Inch CI ](http://inch-ci.org/github/activeadmin/activeadmin.svg?branch=master) ](http://inch-ci.org/github/activeadmin/activeadmin) ## State of the project diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5b9f32cadf1..4cfd02e6286 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,3 +15,6 @@ add_filter 'features/' add_filter 'bundle/' # for Travis end + +require 'codecov' +SimpleCov.formatter = SimpleCov::Formatter::Codecov \ No newline at end of file diff --git a/tasks/test.rake b/tasks/test.rake index 1d711ae91b8..a5c7f1c35d4 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -21,10 +21,6 @@ end desc "Run the full suite using 1 core" task test: ['spec:unit', 'spec:request', 'cucumber', 'cucumber:class_reloading'] -require 'coveralls/rake/task' -Coveralls::RakeTask.new -task test_with_coveralls: [:test, 'coveralls:push'] - namespace :test do def run_tests_against(*versions) From f620ccaf32f959904fd4eb8176be0d696e411edd Mon Sep 17 00:00:00 2001 From: sue445 Date: Wed, 11 Jan 2017 17:22:52 +0900 Subject: [PATCH 0198/3836] Relax kaminari dependency for kaminari 1.0.0 --- activeadmin.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index e20184d74ee..8f172f39549 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |s| s.add_dependency 'inherited_resources', '~> 1.6' s.add_dependency 'jquery-rails' s.add_dependency 'jquery-ui-rails' - s.add_dependency 'kaminari', '~> 0.15' + s.add_dependency 'kaminari', '>= 0.15', '< 2.0' s.add_dependency 'railties', '>= 3.2', '< 5.1' s.add_dependency 'ransack', '~> 1.3' s.add_dependency 'sass-rails' From 5dca3413fa767f3d37f329b74def3096f6496940 Mon Sep 17 00:00:00 2001 From: sue445 Date: Wed, 11 Jan 2017 21:12:56 +0900 Subject: [PATCH 0199/3836] Use kaminari 0.x on ruby 1.9 kaminari 1.x doesn't work on ruby 1.9 https://github.com/kaminari/kaminari/blob/v1.0.0/kaminari-core/lib/kaminari/helpers/paginator.rb#L9 uses ruby 2.0+ syntax --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 45d8339e841..13b0ac7035c 100644 --- a/Gemfile +++ b/Gemfile @@ -21,6 +21,7 @@ if rails_major == '5' end platform :ruby_19 do # Remove this block when we drop support for Ruby 1.9 + gem 'kaminari', '~> 0.15' gem 'mime-types', '< 3' gem 'nokogiri', '< 1.7' gem 'public_suffix', '< 1.5' From 388c89e1b4bbf7f6d595a492dcd45595fe0e329c Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 13 Jan 2017 17:59:05 +0900 Subject: [PATCH 0200/3836] Kaminari repository URL has been changed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 59b15401d79..ae96d466fce 100644 --- a/README.md +++ b/README.md @@ -98,5 +98,5 @@ Tool | Description [Devise]: https://github.com/plataformatec/devise [Formtastic]: https://github.com/justinfrench/formtastic [Inherited Resources]: https://github.com/josevalim/inherited_resources -[Kaminari]: https://github.com/amatsuda/kaminari +[Kaminari]: https://github.com/kaminari/kaminari [Ransack]: https://github.com/activerecord-hackery/ransack From 922fca19ee17b4f25bac04d0cf245e43c2597f8d Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sat, 14 Jan 2017 05:35:57 +0200 Subject: [PATCH 0201/3836] fix empty inputs for date_range filters before this fix when using ransackers or custom ransackable_scopes filters inputs were empty after page reload --- .../inputs/filters/date_range_input.rb | 9 +++- spec/unit/filters/filter_form_builder_spec.rb | 41 +++++++++++++++---- spec/unit/filters/resource_spec.rb | 6 +-- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/lib/active_admin/inputs/filters/date_range_input.rb b/lib/active_admin/inputs/filters/date_range_input.rb index d75df1a2a12..1412d4a59b6 100644 --- a/lib/active_admin/inputs/filters/date_range_input.rb +++ b/lib/active_admin/inputs/filters/date_range_input.rb @@ -24,11 +24,16 @@ def lt_input_name end def input_html_options(input_name = gt_input_name) - current_value = @object.public_send input_name + current_value = begin + #cast value to date object before rendering input + @object.public_send(input_name).to_s.to_date + rescue + nil + end { size: 12, class: "datepicker", maxlength: 10, - value: current_value.respond_to?(:strftime) ? current_value.strftime("%Y-%m-%d") : "" } + value: current_value ? current_value.strftime("%Y-%m-%d") : "" } end end end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index cb8890bb88d..8736acbfdfb 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -1,8 +1,11 @@ require 'rails_helper' class Post - ransacker :custom_searcher do - # nothing to see here + ransacker :custom_title_searcher do |parent| + parent.table[:title] + end + ransacker :custom_created_at_searcher do |parent| + parent.table[:created_at] end end @@ -404,20 +407,42 @@ def view.a_helper_method describe "custom search methods" do it "should work as select" do - body = Capybara.string(filter :custom_searcher, as: :select, collection: ['foo']) - expect(body).to have_selector("select[name='q[custom_searcher]']") + body = Capybara.string(filter :custom_title_searcher, as: :select, collection: ['foo']) + expect(body).to have_selector("select[name='q[custom_title_searcher]']") end it "should work as string" do - body = Capybara.string(filter :custom_searcher, as: :string) - expect(body).to have_selector("input[name='q[custom_searcher]']") + body = Capybara.string(filter :custom_title_searcher, as: :string) + expect(body).to have_selector("input[name='q[custom_title_searcher]']") + end + + describe "custom date range search" do + let(:qteq) { "2010-10-01" } + let(:lteq) { "2010-10-02" } + let(:scope){ Post.search custom_created_at_searcher_gteq_datetime: qteq, custom_created_at_searcher_lteq_datetime: lteq } + let(:body) { Capybara.string(render_filter scope, custom_created_at_searcher: {as: :date_range}) } + + it "should work as date_range" do + expect(body).to have_selector("input[name='q[custom_created_at_searcher_gteq_datetime]'][value='2010-10-01']") + expect(body).to have_selector("input[name='q[custom_created_at_searcher_lteq_datetime]'][value='2010-10-02']") + end + + context "filter value can't be casted to date" do + let(:qteq) { "Ooops" } + let(:lteq) { "Ooops" } + + it "should work display empty filter values" do + expect(body).to have_selector("input[name='q[custom_created_at_searcher_gteq_datetime]'][value='']") + expect(body).to have_selector("input[name='q[custom_created_at_searcher_lteq_datetime]'][value='']") + end + end end end describe "does not support some filter inputs" do it "should fallback to use formtastic inputs" do - body = Capybara.string(filter :custom_searcher, as: :text) - expect(body).to have_selector("textarea[name='q[custom_searcher]']") + body = Capybara.string(filter :custom_title_searcher, as: :text) + expect(body).to have_selector("textarea[name='q[custom_title_searcher]']") end end diff --git a/spec/unit/filters/resource_spec.rb b/spec/unit/filters/resource_spec.rb index 6c4b6335942..533bc2f617e 100644 --- a/spec/unit/filters/resource_spec.rb +++ b/spec/unit/filters/resource_spec.rb @@ -13,7 +13,7 @@ it "should return the defaults if no filters are set" do expect(resource.filters.keys).to match_array([ - :author, :body, :category, :created_at, :custom_searcher, :position, :published_date, :starred, :taggings, :title, :updated_at + :author, :body, :category, :created_at, :custom_created_at_searcher, :custom_title_searcher ,:position, :published_date, :starred, :taggings, :title, :updated_at ]) end @@ -35,7 +35,7 @@ it "should return the defaults without associations if default association filters are disabled on the namespace" do resource.namespace.include_default_association_filters = false expect(resource.filters.keys).to match_array([ - :body, :created_at, :custom_searcher, :position, :published_date, :starred, :title, :updated_at + :body, :created_at, :custom_created_at_searcher, :custom_title_searcher, :position, :published_date, :starred, :title, :updated_at ]) end @@ -104,7 +104,7 @@ resource.add_filter :count, as: :string expect(resource.filters.keys).to match_array([ - :author, :body, :category, :count, :created_at, :custom_searcher, :position, :published_date, :starred, :taggings, :title, :updated_at + :author, :body, :category, :count, :created_at, :custom_created_at_searcher, :custom_title_searcher, :position, :published_date, :starred, :taggings, :title, :updated_at ]) end From 1f1115fcd5708b544cbf436d0e47ed4b2b350d77 Mon Sep 17 00:00:00 2001 From: David Reese Date: Sat, 12 Nov 2016 10:23:18 -0500 Subject: [PATCH 0202/3836] Update filters to work with custom Ransackers Fixes issues created when converting from metasearch. Adds a custom ransacker to the rails_template to demo its interaction with filters. [fixes #3510] --- lib/active_admin/filters/formtastic_addons.rb | 2 +- spec/support/rails_template.rb | 4 ++++ spec/unit/filters/filter_form_builder_spec.rb | 15 +++++++++++++-- spec/unit/filters/resource_spec.rb | 6 +++--- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/active_admin/filters/formtastic_addons.rb b/lib/active_admin/filters/formtastic_addons.rb index 9921a7c666c..e3819177898 100644 --- a/lib/active_admin/filters/formtastic_addons.rb +++ b/lib/active_admin/filters/formtastic_addons.rb @@ -54,7 +54,7 @@ def searchable_has_many_through? end def seems_searchable? - has_predicate? || ransacker? || scope? + has_predicate? || scope? end # If the given method has a predicate (like _eq or _lteq), it's pretty diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index d6a3ccb8693..226f41cde8e 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -46,6 +46,10 @@ class User < ActiveRecord::Base has_one :profile accepts_nested_attributes_for :profile, allow_destroy: true + ransacker :age_in_five_years, type: :numeric, formatter: proc { |v| v.to_i - 5 } do |parent| + parent.table[:age] + end + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes attr_accessible :first_name, :last_name, :username, :age end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index cb8890bb88d..1ce88d712fa 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -4,6 +4,9 @@ class Post ransacker :custom_searcher do # nothing to see here end + ransacker :custom_searcher_numeric, type: :numeric do + # nothing to see here + end end describe ActiveAdmin::Filters::ViewHelper do @@ -403,14 +406,22 @@ def view.a_helper_method describe "custom search methods" do + it "should use the default type of the ransacker" do + body = Capybara.string(filter :custom_searcher_numeric) + expect(body).to have_selector("option[value=custom_searcher_numeric_equals]") + expect(body).to have_selector("option[value=custom_searcher_numeric_greater_than]") + expect(body).to have_selector("option[value=custom_searcher_numeric_less_than]") + end + it "should work as select" do body = Capybara.string(filter :custom_searcher, as: :select, collection: ['foo']) - expect(body).to have_selector("select[name='q[custom_searcher]']") + expect(body).to have_selector("select[name='q[custom_searcher_eq]']") end it "should work as string" do body = Capybara.string(filter :custom_searcher, as: :string) - expect(body).to have_selector("input[name='q[custom_searcher]']") + expect(body).to have_selector("option[value=custom_searcher_contains]") + expect(body).to have_selector("option[value=custom_searcher_starts_with]") end end diff --git a/spec/unit/filters/resource_spec.rb b/spec/unit/filters/resource_spec.rb index 6c4b6335942..12e92d13079 100644 --- a/spec/unit/filters/resource_spec.rb +++ b/spec/unit/filters/resource_spec.rb @@ -13,7 +13,7 @@ it "should return the defaults if no filters are set" do expect(resource.filters.keys).to match_array([ - :author, :body, :category, :created_at, :custom_searcher, :position, :published_date, :starred, :taggings, :title, :updated_at + :author, :body, :category, :created_at, :custom_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :taggings, :title, :updated_at ]) end @@ -35,7 +35,7 @@ it "should return the defaults without associations if default association filters are disabled on the namespace" do resource.namespace.include_default_association_filters = false expect(resource.filters.keys).to match_array([ - :body, :created_at, :custom_searcher, :position, :published_date, :starred, :title, :updated_at + :body, :created_at, :custom_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :title, :updated_at ]) end @@ -104,7 +104,7 @@ resource.add_filter :count, as: :string expect(resource.filters.keys).to match_array([ - :author, :body, :category, :count, :created_at, :custom_searcher, :position, :published_date, :starred, :taggings, :title, :updated_at + :author, :body, :category, :count, :created_at, :custom_searcher, :custom_searcher_numeric, :position, :published_date, :starred, :taggings, :title, :updated_at ]) end From e9a8cdf4dc9cbcb97f37a1af5415572a8a3604e9 Mon Sep 17 00:00:00 2001 From: Yuya Tanaka Date: Sun, 15 Jan 2017 01:47:33 +0900 Subject: [PATCH 0203/3836] Add doc about Formtastic collection_label_methods --- lib/active_admin/application.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/active_admin/application.rb b/lib/active_admin/application.rb index 0214f64b4b1..7dc0209cd0d 100644 --- a/lib/active_admin/application.rb +++ b/lib/active_admin/application.rb @@ -117,6 +117,8 @@ def initialize # Active Admin makes educated guesses when displaying objects, this is # the list of methods it tries calling in order + # Note that Formtastic also has 'collection_label_methods' similar to this + # used by auto generated dropdowns in filter or belongs_to field of Active Admin setting :display_name_methods, [ :display_name, :full_name, :name, From e6231b1c2be07cc44f7541fc50e84b2a739d87ba Mon Sep 17 00:00:00 2001 From: Scott Meves Date: Mon, 16 Jan 2017 13:41:32 -0500 Subject: [PATCH 0204/3836] make namespace route options configurable --- CHANGELOG.md | 1 + lib/active_admin/application.rb | 3 +++ lib/active_admin/router.rb | 4 ++-- spec/unit/routing_spec.rb | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f492759615..1b42dc6e8bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ index download_links: ->{ can?(:view_all_download_links) || [:pdf] } ``` * Comments menu can be customized via configuration passed to `config.comments_menu` [#4187][] by [@drn][] +* Added `config.route_options` to namespace to customize routes [#4467][] by [@stereoscott[]] ### Security Fixes diff --git a/lib/active_admin/application.rb b/lib/active_admin/application.rb index 7dc0209cd0d..6e8eb1772f2 100644 --- a/lib/active_admin/application.rb +++ b/lib/active_admin/application.rb @@ -80,6 +80,9 @@ def initialize # Options that a passed to root_to. inheritable_setting :root_to_options, {} + # Options passed to the routes, i.e. { path: '/custom' } + inheritable_setting :route_options, {} + # Display breadcrumbs inheritable_setting :breadcrumb, true diff --git a/lib/active_admin/router.rb b/lib/active_admin/router.rb index 13c23d7b9be..9d40d27b236 100644 --- a/lib/active_admin/router.rb +++ b/lib/active_admin/router.rb @@ -23,7 +23,7 @@ def define_root_routes(router) if namespace.root? root namespace.root_to_options.merge(to: namespace.root_to) else - namespace namespace.name do + namespace namespace.name, namespace.route_options.dup do root namespace.root_to_options.merge(to: namespace.root_to, as: :root) end end @@ -57,7 +57,7 @@ def define_resource_routes(router) unless config.namespace.root? nested = routes routes = Proc.new do - namespace config.namespace.name do + namespace config.namespace.name, config.namespace.route_options.dup do instance_exec &nested end end diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index 1bb77fac0fd..be6ba701c4e 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -30,6 +30,24 @@ end end + describe "route_options" do + context "with a custom path set in route_options" do + before(:each) do + ActiveAdmin.application.namespaces[:admin].route_options = { path: '/custom-path' } + reload_routes! + end + + after(:all) do + ActiveAdmin.application.namespaces[:admin].route_options = {} + reload_routes! + end + + it "should route using the custom path" do + expect(admin_posts_path).to eq "/custom-path/posts" + end + end + end + describe "standard resources" do context "when in admin namespace" do it "should route the index path" do From 44ec2551b66fb325406af6ac83b6b47811bcde60 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 18 Jan 2017 15:54:13 +0200 Subject: [PATCH 0205/3836] fixed typo in /devise/registrations/new.html.erb --- app/views/active_admin/devise/registrations/new.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/active_admin/devise/registrations/new.html.erb b/app/views/active_admin/devise/registrations/new.html.erb index 899c1f4881f..6bee61dd8be 100644 --- a/app/views/active_admin/devise/registrations/new.html.erb +++ b/app/views/active_admin/devise/registrations/new.html.erb @@ -9,7 +9,7 @@ f.input key, label: t('active_admin.devise.'+key.to_s+'.title'), input_html: { autofocus: index.zero? } } f.input :password, label: t('active_admin.devise.password.title') - f.input :password_confirmation, lable: t('active_admin.devise.password_confirmation.title') + f.input :password_confirmation, label: t('active_admin.devise.password_confirmation.title') end f.actions do f.action :submit, label: t('active_admin.devise.login.submit'), button_html: { value: t('active_admin.devise.sign_up.submit') } From 95c734cc2103d8cf5746ae1c1a0b15f30e03e5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 18 Jan 2017 19:44:22 -0200 Subject: [PATCH 0206/3836] Define workflow for PR merging --- CONTRIBUTING.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aec68e849f3..b03beee336e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -142,3 +142,16 @@ git checkout 325-add-japanese-translations git pull --rebase upstream master git push -f 325-add-japanese-translations ``` + +### 9. Merging a PR (maintainers only) + +A PR can only be merged into master by a maintainer if: + +* It is passing CI. +* It has been approved by at least another maintainer. +* It has no requested changes. +* It is up to date with current master. +* It has been opened for at least 48h. + +Any maintainer is allowed to merge a PR if all of these conditions are +met. From 08eedca889f064f893c2257cc006af7a772089b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 19 Jan 2017 06:54:48 -0200 Subject: [PATCH 0207/3836] Clarify roles and approvals. --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b03beee336e..4e10e863e36 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -148,7 +148,8 @@ git push -f 325-add-japanese-translations A PR can only be merged into master by a maintainer if: * It is passing CI. -* It has been approved by at least another maintainer. +* It has been approved by at least two maintainers. If it was a maintainer who + opened the PR, only one extra approval is needed. * It has no requested changes. * It is up to date with current master. * It has been opened for at least 48h. From 2165ca9496425f1e9f201a78a6b0fc639d0541d1 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Fri, 20 Jan 2017 12:35:46 +0200 Subject: [PATCH 0208/3836] fixed merge --- spec/unit/filters/filter_form_builder_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index e6fd983f5cc..a7bfc2bb840 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -424,7 +424,7 @@ def view.a_helper_method it "should work as string" do body = Capybara.string(filter :custom_title_searcher, as: :string) expect(body).to have_selector("input[name='q[custom_title_searcher_contains]']") - expect(body).to have_selector("input[name='q[custom_searcher_starts_with]']") + expect(body).to have_selector("input[name='q[custom_title_searcher_starts_with]']") end describe "custom date range search" do From d172d58c4a7e3e6e2831400419963dff49287d34 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Fri, 20 Jan 2017 14:28:32 +0200 Subject: [PATCH 0209/3836] fixed wrong selectors for ransackers filters specs --- spec/unit/filters/filter_form_builder_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index a7bfc2bb840..33a0d909279 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -423,8 +423,8 @@ def view.a_helper_method it "should work as string" do body = Capybara.string(filter :custom_title_searcher, as: :string) - expect(body).to have_selector("input[name='q[custom_title_searcher_contains]']") - expect(body).to have_selector("input[name='q[custom_title_searcher_starts_with]']") + expect(body).to have_selector("option[name='q[custom_title_searcher_contains]']") + expect(body).to have_selector("option[name='q[custom_title_searcher_starts_with]']") end describe "custom date range search" do From 80bae578b1aeca5d60e9f4d80e278861e97d63b6 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Fri, 20 Jan 2017 14:51:20 +0200 Subject: [PATCH 0210/3836] fixed wrong selectors for ransackers filters specs --- spec/unit/filters/filter_form_builder_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 33a0d909279..34f9585e6c5 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -423,8 +423,8 @@ def view.a_helper_method it "should work as string" do body = Capybara.string(filter :custom_title_searcher, as: :string) - expect(body).to have_selector("option[name='q[custom_title_searcher_contains]']") - expect(body).to have_selector("option[name='q[custom_title_searcher_starts_with]']") + expect(body).to have_selector("option[value=custom_title_searcher_contains]") + expect(body).to have_selector("option[value=custom_title_searcher_starts_with]") end describe "custom date range search" do From 0abff0366269c9920b4fe92956382120ba15db07 Mon Sep 17 00:00:00 2001 From: Roman Shatsov Date: Thu, 19 Dec 2013 12:08:19 +0300 Subject: [PATCH 0211/3836] Add ResourceLocalizer --- features/i18n.feature | 11 ++++++ features/step_definitions/i18n_steps.rb | 8 +++++ features/support/paths.rb | 3 ++ lib/active_admin.rb | 1 + lib/active_admin/localizers.rb | 11 ++++++ .../localizers/resource_localizer.rb | 35 +++++++++++++++++++ lib/active_admin/resource/action_items.rb | 11 +++--- lib/active_admin/resource/scopes.rb | 1 + lib/active_admin/scope.rb | 3 +- lib/active_admin/views/components/scopes.rb | 5 ++- lib/active_admin/views/pages/form.rb | 3 +- lib/active_admin/views/pages/show.rb | 3 +- spec/unit/config_shared_examples.rb | 13 +++++++ .../localizers/resource_localizer_spec.rb | 22 ++++++++++++ spec/unit/scope_spec.rb | 24 +++++++++++++ 15 files changed, 143 insertions(+), 11 deletions(-) create mode 100644 lib/active_admin/localizers.rb create mode 100644 lib/active_admin/localizers/resource_localizer.rb create mode 100644 spec/unit/localizers/resource_localizer_spec.rb diff --git a/features/i18n.feature b/features/i18n.feature index 3948be7b745..86030c9a957 100644 --- a/features/i18n.feature +++ b/features/i18n.feature @@ -41,3 +41,14 @@ Feature: Internationalization When I go to the dashboard When I follow "Bookstores" Then I should see "Download this:" + + Scenario: Overriding resource details table title + Given a configuration of: + """ + ActiveAdmin.register Post + """ + And String "Post detailed information" corresponds to "resources.post.details" + And I am logged in + And a post exists + When I go to the last post's show page + Then I should see "Post detailed information" diff --git a/features/step_definitions/i18n_steps.rb b/features/step_definitions/i18n_steps.rb index bc93daf0ea1..53f9c7bd1d6 100644 --- a/features/step_definitions/i18n_steps.rb +++ b/features/step_definitions/i18n_steps.rb @@ -1,3 +1,11 @@ +Given /^String "([^"]*)" corresponds to "([^"]*)"$/ do |translation, key| + *seq, last_key = key.split('.') + result = seq.reverse.inject({last_key.to_sym => translation}) do |temp_result, nested_key| + {nested_key.to_sym => temp_result} + end + I18n.backend.store_translations :en, active_admin: result +end + When /^I set my locale to "([^"]*)"$/ do |lang| I18n.locale = lang end diff --git a/features/support/paths.rb b/features/support/paths.rb index 325d902ebd9..42740996a94 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -45,6 +45,9 @@ def path_to(page_name) when /^the last author's last post page$/ admin_user_post_path(User.last, Post.where(author_id: User.last.id).last) + when /^the last post's show page$/ + admin_post_path(Post.last) + when /^the last post's edit page$/ edit_admin_post_path(Post.last) diff --git a/lib/active_admin.rb b/lib/active_admin.rb index 5f14f179819..1d21bc4efc5 100644 --- a/lib/active_admin.rb +++ b/lib/active_admin.rb @@ -36,6 +36,7 @@ module ActiveAdmin autoload :Event, 'active_admin/event' autoload :FormBuilder, 'active_admin/form_builder' autoload :Inputs, 'active_admin/inputs' + autoload :Localizers, 'active_admin/localizers' autoload :Menu, 'active_admin/menu' autoload :MenuCollection, 'active_admin/menu_collection' autoload :MenuItem, 'active_admin/menu_item' diff --git a/lib/active_admin/localizers.rb b/lib/active_admin/localizers.rb new file mode 100644 index 00000000000..7d84b6293ba --- /dev/null +++ b/lib/active_admin/localizers.rb @@ -0,0 +1,11 @@ +require 'active_admin/localizers/resource_localizer' + +module ActiveAdmin + module Localizers + class << self + def resource(active_admin_config) + ResourceLocalizer.from_resource(active_admin_config) + end + end + end +end diff --git a/lib/active_admin/localizers/resource_localizer.rb b/lib/active_admin/localizers/resource_localizer.rb new file mode 100644 index 00000000000..f2247b3348e --- /dev/null +++ b/lib/active_admin/localizers/resource_localizer.rb @@ -0,0 +1,35 @@ +module ActiveAdmin + module Localizers + class ResourceLocalizer + class << self + def from_resource(resource_config) + new(resource_config.resource_name.i18n_key, resource_config.resource_label) + end + + def translate(key, options) + new(options.delete(:model_name), options.delete(:model)).translate(key, options) + end + alias_method :t, :translate + end + + def initialize(model_name, model = nil) + @model_name = model_name + @model = model || model_name.to_s.titleize + end + + def translate(key, options = {}) + scope = options.delete(:scope) + specific_key = array_to_key('resources', @model_name, scope, key) + defaults = [array_to_key(scope, key), key.to_s.titleize] + ::I18n.t specific_key, options.reverse_merge(model: @model, default: defaults, scope: 'active_admin') + end + alias_method :t, :translate + + protected + + def array_to_key(*arr) + arr.flatten.compact.join('.').to_sym + end + end + end +end diff --git a/lib/active_admin/resource/action_items.rb b/lib/active_admin/resource/action_items.rb index 1aae736ecee..b2a09094f61 100644 --- a/lib/active_admin/resource/action_items.rb +++ b/lib/active_admin/resource/action_items.rb @@ -64,7 +64,8 @@ def add_default_action_items def add_default_new_action_item add_action_item :new, only: :index do if controller.action_methods.include?('new') && authorized?(ActiveAdmin::Auth::CREATE, active_admin_config.resource_class) - link_to I18n.t('active_admin.new_model', model: active_admin_config.resource_label), new_resource_path + localizer = ActiveAdmin::Localizers.resource(active_admin_config) + link_to localizer.t(:new_model), new_resource_path end end end @@ -73,7 +74,8 @@ def add_default_new_action_item def add_default_edit_action_item add_action_item :edit, only: :show do if controller.action_methods.include?('edit') && authorized?(ActiveAdmin::Auth::UPDATE, resource) - link_to I18n.t('active_admin.edit_model', model: active_admin_config.resource_label), edit_resource_path(resource) + localizer = ActiveAdmin::Localizers.resource(active_admin_config) + link_to localizer.t(:edit_model), edit_resource_path(resource) end end end @@ -82,8 +84,9 @@ def add_default_edit_action_item def add_default_show_action_item add_action_item :destroy, only: :show do if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource) - link_to I18n.t('active_admin.delete_model', model: active_admin_config.resource_label), resource_path(resource), - method: :delete, data: {confirm: I18n.t('active_admin.delete_confirmation')} + localizer = ActiveAdmin::Localizers.resource(active_admin_config) + link_to localizer.t(:delete_model), resource_path(resource), method: :delete, + data: {confirm: localizer.t(:delete_confirmation)} end end end diff --git a/lib/active_admin/resource/scopes.rb b/lib/active_admin/resource/scopes.rb index 5c834f64b3d..869dd08b025 100644 --- a/lib/active_admin/resource/scopes.rb +++ b/lib/active_admin/resource/scopes.rb @@ -31,6 +31,7 @@ def scope(*args, &block) title = args[0] rescue nil method = args[1] rescue nil + options[:localizer] ||= ActiveAdmin::Localizers.resource(self) scope = ActiveAdmin::Scope.new(title, method, options, &block) # Finds and replaces a scope by the same name if it already exists diff --git a/lib/active_admin/scope.rb b/lib/active_admin/scope.rb index 8f6cda832d1..b504d399c59 100644 --- a/lib/active_admin/scope.rb +++ b/lib/active_admin/scope.rb @@ -38,6 +38,7 @@ def initialize(name, method = nil, options = {}, &block) @scope_method = nil if @scope_method == :all @scope_method, @scope_block = nil, block if block_given? + @localizer = options[:localizer] @show_count = options.fetch(:show_count, true) @display_if_block = options[:if] || proc{ true } @default_block = options[:default] || proc{ false } @@ -47,7 +48,7 @@ def name case @name when Proc then @name.call.to_s when String then @name - when Symbol then @name.to_s.titleize + when Symbol then @localizer ? @localizer.t(@name, scope: 'scopes') : @name.to_s.titleize else @name.to_s end end diff --git a/lib/active_admin/views/components/scopes.rb b/lib/active_admin/views/components/scopes.rb index e5700a5b06c..972072167b4 100644 --- a/lib/active_admin/views/components/scopes.rb +++ b/lib/active_admin/views/components/scopes.rb @@ -31,11 +31,10 @@ def build(scopes, options = {}) def build_scope(scope, options) li class: classes_for_scope(scope) do - scope_name = I18n.t "active_admin.scopes.#{scope.id}", default: scope.name - params = request.query_parameters.except :page, :scope, :commit, :format + params = request.query_parameters.except :page, :scope, :commit, :format a href: url_for(scope: scope.id, params: params), class: 'table_tools_button' do - text_node scope_name + text_node scope.name span class: 'count' do "(#{get_scope_count(scope)})" end if options[:scope_count] && scope.show_count diff --git a/lib/active_admin/views/pages/form.rb b/lib/active_admin/views/pages/form.rb index 801e0f45fd9..154279db7e6 100644 --- a/lib/active_admin/views/pages/form.rb +++ b/lib/active_admin/views/pages/form.rb @@ -8,8 +8,7 @@ def title if form_presenter[:title] render_or_call_method_or_proc_on(resource, form_presenter[:title]) else - assigns[:page_title] || I18n.t("active_admin.#{normalized_action}_model", - model: active_admin_config.resource_label) + assigns[:page_title] || ActiveAdmin::Localizers.resource(active_admin_config).t("#{normalized_action}_model") end end diff --git a/lib/active_admin/views/pages/show.rb b/lib/active_admin/views/pages/show.rb index 407823bb2c1..5cefc168c79 100644 --- a/lib/active_admin/views/pages/show.rb +++ b/lib/active_admin/views/pages/show.rb @@ -25,7 +25,8 @@ def main_content end def attributes_table(*args, &block) - panel(I18n.t('active_admin.details', model: active_admin_config.resource_label)) do + table_title = ActiveAdmin::Localizers.resource(active_admin_config).t(:details) + panel(table_title) do attributes_table_for resource, *args, &block end end diff --git a/spec/unit/config_shared_examples.rb b/spec/unit/config_shared_examples.rb index f4f9ccb2ce6..90317c18638 100644 --- a/spec/unit/config_shared_examples.rb +++ b/spec/unit/config_shared_examples.rb @@ -57,3 +57,16 @@ end end + +shared_examples_for "ActiveAdmin::Localizers::ResourceLocalizer" do + it "should use proper translation" do + string = ActiveAdmin::Localizers::ResourceLocalizer.t(action, model: model, model_name: model_name) + expect(string).to eq translation + end + + it "should accessible via ActiveAdmin::Localizers" do + resource = double(resource_label: model, resource_name: double(i18n_key: model_name)) + localizer = ActiveAdmin::Localizers.resource(resource) + expect(localizer.t(action)).to eq translation + end +end diff --git a/spec/unit/localizers/resource_localizer_spec.rb b/spec/unit/localizers/resource_localizer_spec.rb new file mode 100644 index 00000000000..cc696123cb8 --- /dev/null +++ b/spec/unit/localizers/resource_localizer_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' +require File.expand_path('../config_shared_examples', File.dirname(__FILE__)) + +describe ActiveAdmin::Localizers::ResourceLocalizer do + let(:action) { 'new_model' } + let(:model) { 'Comment' } + let(:model_name) { 'comment' } + + it_behaves_like "ActiveAdmin::Localizers::ResourceLocalizer" do + let(:translation) { 'New Comment' } + end + + describe "model action specified" do + before do + I18n.backend.store_translations :en, active_admin: {resources: {comment: {new_model: 'Write comment'}}} + end + + it_behaves_like "ActiveAdmin::Localizers::ResourceLocalizer" do + let(:translation) { 'Write comment' } + end + end +end diff --git a/spec/unit/scope_spec.rb b/spec/unit/scope_spec.rb index 4ae77563381..24349c524f6 100644 --- a/spec/unit/scope_spec.rb +++ b/spec/unit/scope_spec.rb @@ -139,6 +139,30 @@ end end + context "with scope method and localizer" do + let(:localizer) do + loc = double(:localizer) + allow(loc).to receive(:t).with(:published, scope: 'scopes').and_return("All published") + loc + end + let(:scope) { ActiveAdmin::Scope.new :published, :published, localizer: localizer } + + describe '#name' do + subject { super().name } + it { is_expected.to eq("All published")} + end + + describe '#id' do + subject { super().id } + it { is_expected.to eq("published")} + end + + describe '#scope_method' do + subject { super().scope_method } + it { is_expected.to eq(:published) } + end + end + end # describe "creating a scope" describe "#display_if_block" do From 75b75074dc38a5920d97c7cf69ef46d3ccf7ae63 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Wed, 18 Jan 2017 21:31:56 -0500 Subject: [PATCH 0212/3836] Document #2823 --- docs/2-resource-customization.md | 7 +++++++ docs/3-index-pages.md | 2 ++ 2 files changed, 9 insertions(+) diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index cc7c59ad71c..6dc888481eb 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -94,6 +94,13 @@ ActiveAdmin.register Post do end ``` +## Renaming Action Items + +One can set custom button name and page title for new, edit, and destroy actions/pages +at the resource level by providing a resource specific translation. +For example to change 'New Offer' to 'Make an Offer' +set `active_admin.resources.offer.new_model`. + ## Rename the Resource By default, any references to the resource (menu, routes, buttons, etc) in the diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index e076a00d4ad..1be1063d428 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -186,6 +186,8 @@ scope "Published", if: proc { current_admin_user.can? :manage, Posts } do |posts end ``` +Scopes can be labelled with a translation, e.g. `activerecord.scopes.invoice.expired`. + ## Index default sort order You can define the default sort order for index pages: From 64f609973beb9c02e2b302abc6b3787b64bf0791 Mon Sep 17 00:00:00 2001 From: Anton Chumakov Date: Mon, 19 Sep 2016 15:53:15 +0300 Subject: [PATCH 0213/3836] Change the way of assigning template variables `ActionView::Base#assign` method removes all previous view variable assignments from ActionView::Base `assigns` hash if there are any. For example: template.assigns # => {page_title: "Awesome Title"} template.assign(has_many_block: true) # this will clear the `assigns` hash template.assigns # => {has_many_block: true} This commit changes the way of assigning template variables, to avoid previously assigned values loss: template.assigns[:has_many_block] = true --- lib/active_admin/form_builder.rb | 2 +- lib/active_admin/views/components/active_admin_form.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/form_builder.rb b/lib/active_admin/form_builder.rb index 8c98476e66b..727d6375fc5 100644 --- a/lib/active_admin/form_builder.rb +++ b/lib/active_admin/form_builder.rb @@ -64,7 +64,7 @@ def has_many(assoc, options = {}, &block) template.concat has_many_actions(has_many_form, builder_options, "".html_safe) end - template.assign(has_many_block: true) + template.assigns[:has_many_block] = true contents = without_wrapper { inputs(options, &form_block) } || "".html_safe if builder_options[:new_record] diff --git a/lib/active_admin/views/components/active_admin_form.rb b/lib/active_admin/views/components/active_admin_form.rb index 6441571085b..2d5202c9f31 100644 --- a/lib/active_admin/views/components/active_admin_form.rb +++ b/lib/active_admin/views/components/active_admin_form.rb @@ -43,7 +43,7 @@ def build(resource, options = {}, &block) def inputs(*args, &block) if block_given? - form_builder.template.assign(has_many_block: true) + form_builder.template.assigns[:has_many_block] = true end if block_given? && block.arity == 0 wrapped_block = proc do From 21809a420d873eb7a886839896043984607d6792 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sun, 22 Jan 2017 01:25:25 +0200 Subject: [PATCH 0214/3836] updated old hash syntax, fixed typos --- Guardfile | 2 +- features/action_item.feature | 4 +-- features/authorization_cancan.feature | 6 ++-- features/belongs_to.feature | 2 +- features/comments/commenting.feature | 14 ++++----- features/edit_page.feature | 6 ++-- features/index/batch_actions.feature | 12 ++++---- features/index/filters.feature | 8 ++--- features/index/format_as_csv.feature | 22 +++++++------- features/index/formats.feature | 8 ++--- features/index/index_as_block.feature | 2 +- features/index/index_as_blog.feature | 12 ++++---- features/index/index_as_grid.feature | 6 ++-- features/index/index_as_table.feature | 10 +++---- features/index/index_blank_slate.feature | 8 ++--- features/index/index_parameters.feature | 20 ++++++------- features/index/index_scope_to.feature | 4 +-- features/index/index_scopes.feature | 30 +++++++++---------- features/index/page_title.feature | 6 ++-- features/index/pagination.feature | 2 +- features/index/switch_index_view.feature | 16 +++++----- features/menu.feature | 6 ++-- features/new_page.feature | 4 +-- features/registering_assets.feature | 2 +- features/registering_pages.feature | 4 +-- features/registering_resources.feature | 2 +- features/show/page_title.feature | 6 ++-- features/sidebar_sections.feature | 12 ++++---- features/specifying_actions.feature | 6 ++-- .../views/batch_action_selector.rb | 2 +- .../views/components/dropdown_menu.rb | 4 +-- .../active_admin/devise/devise_generator.rb | 4 +-- spec/rails_helper.rb | 2 +- spec/requests/default_namespace_spec.rb | 2 +- spec/requests/stylesheets_spec.rb | 2 +- .../templates/policies/application_policy.rb | 2 +- .../resource_controller/decorators_spec.rb | 2 +- tasks/parallel_tests.rake | 6 ++-- tasks/test.rake | 2 +- 39 files changed, 135 insertions(+), 135 deletions(-) diff --git a/Guardfile b/Guardfile index ada15e73388..e2270e628f5 100644 --- a/Guardfile +++ b/Guardfile @@ -1,6 +1,6 @@ # More info at https://github.com/guard/guard#readme -guard 'rspec', :all_on_start => false, :version => 2 do +guard 'rspec', all_on_start: false, version: 2 do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/active_admin/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec/" } diff --git a/features/action_item.feature b/features/action_item.feature index 17d5ed37b59..5f3e0124e52 100644 --- a/features/action_item.feature +++ b/features/action_item.feature @@ -32,7 +32,7 @@ Feature: Action Item Given a configuration of: """ ActiveAdmin.register Post do - action_item :embiggen, :if => proc{ !current_active_admin_user.nil? } do + action_item :embiggen, if: proc{ !current_active_admin_user.nil? } do link_to "Embiggen", '/' end end @@ -54,7 +54,7 @@ Feature: Action Item Given a configuration of: """ ActiveAdmin.register Post do - action_item :embiggen, :if => proc{ current_active_admin_user.nil? } do + action_item :embiggen, if: proc{ current_active_admin_user.nil? } do link_to "Embiggen", '/' end end diff --git a/features/authorization_cancan.feature b/features/authorization_cancan.feature index 30f87ef6f0a..d147a5d4551 100644 --- a/features/authorization_cancan.feature +++ b/features/authorization_cancan.feature @@ -12,12 +12,12 @@ Feature: Authorizing Access using CanCan def initialize(user) # Manage Posts - can [:edit, :destroy], Post, :author_id => user.id + can [:edit, :destroy], Post, author_id: user.id can :read, Post # View Pages - can :read, ActiveAdmin::Page, :name => "Dashboard" - cannot :read, ActiveAdmin::Page, :name => "No Access" + can :read, ActiveAdmin::Page, name: "Dashboard" + cannot :read, ActiveAdmin::Page, name: "No Access" end end diff --git a/features/belongs_to.feature b/features/belongs_to.feature index fb48034096c..ab5f5f06edc 100644 --- a/features/belongs_to.feature +++ b/features/belongs_to.feature @@ -42,7 +42,7 @@ Feature: Belongs To """ ActiveAdmin.register User ActiveAdmin.register Post do - belongs_to :user, :optional => true + belongs_to :user, optional: true end """ When I go to the last author's posts diff --git a/features/comments/commenting.feature b/features/comments/commenting.feature index de011d8bca2..7a46ad015e0 100644 --- a/features/comments/commenting.feature +++ b/features/comments/commenting.feature @@ -40,8 +40,8 @@ Feature: Commenting Given a configuration of: """ ActiveAdmin.application.namespace(:new_namespace).comments = false - ActiveAdmin.register Post, :namespace => :new_namespace - ActiveAdmin.register AdminUser, :namespace => :new_namespace + ActiveAdmin.register Post, namespace: :new_namespace + ActiveAdmin.register AdminUser, namespace: :new_namespace """ Given I am logged in When I am on the index page for posts in the new_namespace namespace @@ -52,10 +52,10 @@ Feature: Commenting Given a configuration of: """ ActiveAdmin.application.namespace(:new_namespace).comments = false - ActiveAdmin.register Post, :namespace => :new_namespace do + ActiveAdmin.register Post, namespace: :new_namespace do config.comments = true end - ActiveAdmin.register AdminUser, :namespace => :new_namespace + ActiveAdmin.register AdminUser, namespace: :new_namespace """ Given I am logged in When I am on the index page for posts in the new_namespace namespace @@ -66,8 +66,8 @@ Feature: Commenting Given a show configuration of: """ ActiveAdmin.register Post - ActiveAdmin.register Post, :namespace => :public - ActiveAdmin.register AdminUser, :namespace => :public + ActiveAdmin.register Post, namespace: :public + ActiveAdmin.register AdminUser, namespace: :public """ When I add a comment "Hello world in admin namespace" Then I should see "Hello world in admin namespace" @@ -87,7 +87,7 @@ Feature: Commenting Scenario: Creating a comment on an aliased resource Given a configuration of: """ - ActiveAdmin.register Post, :as => "Article" + ActiveAdmin.register Post, as: "Article" """ Given I am logged in When I am on the index page for articles diff --git a/features/edit_page.feature b/features/edit_page.feature index 8198060f9e3..ccb8d546d6f 100644 --- a/features/edit_page.feature +++ b/features/edit_page.feature @@ -65,7 +65,7 @@ Feature: Edit Page ActiveAdmin.register Post do permit_params :category, :author, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 - form :html => {} do |f| + form html: {} do |f| f.inputs "Your Post" do f.input :title f.input :body @@ -94,7 +94,7 @@ Feature: Edit Page Given "app/views/admin/posts/_form.html.erb" contains: """ <% url = @post.new_record? ? admin_posts_path : admin_post_path(@post) %> - <%= active_admin_form_for @post, :url => url do |f| + <%= active_admin_form_for @post, url: url do |f| f.inputs :title, :body f.actions end %> @@ -104,7 +104,7 @@ Feature: Edit Page ActiveAdmin.register Post do permit_params :category, :author, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 - form :partial => "form" + form partial: "form" end """ Given I follow "Edit" diff --git a/features/index/batch_actions.feature b/features/index/batch_actions.feature index 3a12e410c29..bbdc6d77e13 100644 --- a/features/index/batch_actions.feature +++ b/features/index/batch_actions.feature @@ -83,7 +83,7 @@ Feature: Batch Actions """ ActiveAdmin.register Post do batch_action(:flag) do - redirect_to collection_path, :notice => "Successfully flagged 10 posts" + redirect_to collection_path, notice: "Successfully flagged 10 posts" end end """ @@ -119,8 +119,8 @@ Feature: Batch Actions And an index configuration of: """ ActiveAdmin.register Post do - batch_action(:flag, :if => proc { true }) {} - batch_action(:unflag, :if => proc { false }) {} + batch_action(:flag, if: proc { true }) {} + batch_action(:unflag, if: proc { false }) {} end """ Then I should see the batch action :flag "Flag Selected" @@ -131,9 +131,9 @@ Feature: Batch Actions And an index configuration of: """ ActiveAdmin.register Post do - batch_action(:test, :priority => 3) {} - batch_action(:flag, :priority => 2) {} - batch_action(:unflag, :priority => 1) {} + batch_action(:test, priority: 3) {} + batch_action(:flag, priority: 2) {} + batch_action(:unflag, priority: 1) {} end """ Then the 4th batch action should be "Delete Selected" diff --git a/features/index/filters.feature b/features/index/filters.feature index 3a1daac910a..0aac6b229fc 100644 --- a/features/index/filters.feature +++ b/features/index/filters.feature @@ -60,7 +60,7 @@ Feature: Index Filtering And an index configuration of: """ ActiveAdmin.register Post do - filter :author, :as => :check_boxes + filter :author, as: :check_boxes end """ When I press "Filter" @@ -74,7 +74,7 @@ Feature: Index Filtering And an index configuration of: """ ActiveAdmin.register Post do - filter :author, :as => :check_boxes + filter :author, as: :check_boxes end """ When I check "Jane Doe" @@ -134,7 +134,7 @@ Feature: Index Filtering And an index configuration of: """ ActiveAdmin.register Category do - filter :authors, :as => :check_boxes + filter :authors, as: :check_boxes end """ When I press "Filter" @@ -149,7 +149,7 @@ Feature: Index Filtering And an index configuration of: """ ActiveAdmin.register Category do - filter :authors, :as => :check_boxes + filter :authors, as: :check_boxes end """ When I check "Jane Doe" diff --git a/features/index/format_as_csv.feature b/features/index/format_as_csv.feature index 1f082a0e9bc..556d48d17b6 100644 --- a/features/index/format_as_csv.feature +++ b/features/index/format_as_csv.feature @@ -18,7 +18,7 @@ Feature: Format as CSV Scenario: Default with alias Given a configuration of: """ - ActiveAdmin.register Post, :as => "MyArticle" + ActiveAdmin.register Post, as: "MyArticle" """ And 1 post exists When I am on the index page for my_articles @@ -48,7 +48,7 @@ Feature: Format as CSV Given a configuration of: """ ActiveAdmin.register Post do - csv :col_sep => ';' do + csv col_sep: ';' do column :title column :body end @@ -65,7 +65,7 @@ Feature: Format as CSV Given a configuration of: """ ActiveAdmin.register Post do - csv :force_quotes => true, :byte_order_mark => "" do + csv force_quotes: true, byte_order_mark: "" do column :title column :body end @@ -82,7 +82,7 @@ Feature: Format as CSV Scenario: With default CSV separator option Given a configuration of: """ - ActiveAdmin.application.csv_options = { :col_sep => ';' } + ActiveAdmin.application.csv_options = { col_sep: ';' } ActiveAdmin.register Post do csv do column :title @@ -100,7 +100,7 @@ Feature: Format as CSV Scenario: With default CSV options Given a configuration of: """ - ActiveAdmin.application.csv_options = {:col_sep => ',', :force_quotes => true} + ActiveAdmin.application.csv_options = {col_sep: ',', force_quotes: true} ActiveAdmin.register Post do csv do column :title @@ -119,9 +119,9 @@ Feature: Format as CSV Scenario: Without CVS column names explicitely specified Given a configuration of: """ - ActiveAdmin.application.csv_options = {:col_sep => ',', :force_quotes => true} + ActiveAdmin.application.csv_options = {col_sep: ',', force_quotes: true} ActiveAdmin.register Post do - csv :column_names => true do + csv column_names: true do column :title column :body end @@ -137,9 +137,9 @@ Feature: Format as CSV Scenario: Without CVS column names Given a configuration of: """ - ActiveAdmin.application.csv_options = {:col_sep => ',', :force_quotes => true} + ActiveAdmin.application.csv_options = {col_sep: ',', force_quotes: true} ActiveAdmin.register Post do - csv :column_names => false do + csv column_names: false do column :title column :body end @@ -155,7 +155,7 @@ Feature: Format as CSV Given a configuration of: """ ActiveAdmin.register Post do - csv :encoding => 'SJIS' do + csv encoding: 'SJIS' do column :title column :body end @@ -169,7 +169,7 @@ Feature: Format as CSV Scenario: With default encoding CSV options Given a configuration of: """ - ActiveAdmin.application.csv_options = { :encoding => 'SJIS' } + ActiveAdmin.application.csv_options = { encoding: 'SJIS' } ActiveAdmin.register Post do csv do column :title diff --git a/features/index/formats.feature b/features/index/formats.feature index ad8a0474adf..1561139a8be 100644 --- a/features/index/formats.feature +++ b/features/index/formats.feature @@ -15,7 +15,7 @@ Feature: Index Formats Given an index configuration of: """ ActiveAdmin.register Post do - index :download_links => false + index download_links: false end """ And 1 post exists @@ -28,7 +28,7 @@ Feature: Index Formats Given an index configuration of: """ ActiveAdmin.register Post do - index :download_links => [:pdf] + index download_links: [:pdf] end """ And 1 post exists @@ -42,7 +42,7 @@ Feature: Index Formats Given an index configuration of: """ ActiveAdmin.register Post do - index :download_links => proc { false } + index download_links: proc { false } end """ And 1 post exists @@ -55,7 +55,7 @@ Feature: Index Formats Given an index configuration of: """ ActiveAdmin.register Post do - index :download_links => -> { [:csv] } + index download_links: -> { [:csv] } end """ And 1 post exists diff --git a/features/index/index_as_block.feature b/features/index/index_as_block.feature index ce06ac46e88..3449284998b 100644 --- a/features/index/index_as_block.feature +++ b/features/index/index_as_block.feature @@ -7,7 +7,7 @@ Feature: Index as Block And an index configuration of: """ ActiveAdmin.register Post do - index :as => :block do |post| + index as: :block do |post| span(link_to(post.title, admin_post_path(post))) end end diff --git a/features/index/index_as_blog.feature b/features/index/index_as_blog.feature index 68b171f2ca5..360b1200c01 100644 --- a/features/index/index_as_blog.feature +++ b/features/index/index_as_blog.feature @@ -7,7 +7,7 @@ Feature: Index as Blog And an index configuration of: """ ActiveAdmin.register Post do - index :as => :blog + index as: :blog end """ And I am logged in @@ -20,7 +20,7 @@ Feature: Index as Blog And an index configuration of: """ ActiveAdmin.register Post do - index :as => :blog do + index as: :blog do title :title body :body end @@ -35,7 +35,7 @@ Feature: Index as Blog And an index configuration of: """ ActiveAdmin.register Post do - index :as => :blog do + index as: :blog do title do |post| post.title + " From Block" end @@ -54,12 +54,12 @@ Feature: Index as Blog And an index configuration of: """ ActiveAdmin.register Post do - index :as => :blog do + index as: :blog do title do |post| - span(:class => :title_span) { post.title + " From Block " } + span(class: :title_span) { post.title + " From Block " } end body do |post| - span(:class => :body_span) { post.body + " From Block" } + span(class: :body_span) { post.body + " From Block" } end end end diff --git a/features/index/index_as_grid.feature b/features/index/index_as_grid.feature index 5a65418133e..2968f62bed8 100644 --- a/features/index/index_as_grid.feature +++ b/features/index/index_as_grid.feature @@ -7,7 +7,7 @@ Feature: Index as Grid And an index configuration of: """ ActiveAdmin.register Post do - index :as => :grid do |post| + index as: :grid do |post| h2 auto_link(post) end end @@ -21,7 +21,7 @@ Feature: Index as Grid And an index configuration of: """ ActiveAdmin.register Post do - index :as => :grid, :columns => 1 do |post| + index as: :grid, columns: 1 do |post| h2 auto_link(post) end end @@ -35,7 +35,7 @@ Feature: Index as Grid And an index configuration of: """ ActiveAdmin.register Post do - index :as => :grid, :columns => 2 do |post| + index as: :grid, columns: 2 do |post| h2 auto_link(post) end end diff --git a/features/index/index_as_table.feature b/features/index/index_as_table.feature index 7eb8c62c741..74b0ea777dd 100644 --- a/features/index/index_as_table.feature +++ b/features/index/index_as_table.feature @@ -116,7 +116,7 @@ Feature: Index as Table index do column :category actions do |resource| - link_to 'Custom Action', edit_admin_post_path(resource), :class => 'member_link' + link_to 'Custom Action', edit_admin_post_path(resource), class: 'member_link' end end end @@ -135,8 +135,8 @@ Feature: Index as Table index do column :category - actions :defaults => false do |resource| - link_to 'Custom Action', edit_admin_post_path(resource), :class => 'member_link' + actions defaults: false do |resource| + link_to 'Custom Action', edit_admin_post_path(resource), class: 'member_link' end end end @@ -175,7 +175,7 @@ Feature: Index as Table index do column :category - actions :defaults => false, dropdown: true do |resource| + actions defaults: false, dropdown: true do |resource| item 'Custom Action', edit_admin_post_path(resource) end end @@ -274,7 +274,7 @@ Feature: Index as Table index do column :id column :title - column("Title Length", :sortable => :title_length) { |post| post.title_length } + column("Title Length", sortable: :title_length) { |post| post.title_length } end end """ diff --git a/features/index/index_blank_slate.feature b/features/index/index_blank_slate.feature index 2a8acfe901f..cb1b25aa1e8 100644 --- a/features/index/index_blank_slate.feature +++ b/features/index/index_blank_slate.feature @@ -9,7 +9,7 @@ Feature: Index Blank Slate batch_action :favourite do # nothing end - scope :all, :default => true + scope :all, default: true end """ Then I should not see a sortable table header @@ -33,7 +33,7 @@ Feature: Index Blank Slate Given an index configuration of: """ ActiveAdmin.register Post do - index :as => :grid do |post| + index as: :grid do |post| h2 auto_link(post) end end @@ -44,7 +44,7 @@ Feature: Index Blank Slate Given an index configuration of: """ ActiveAdmin.register Post do - index :as => :block do |post| + index as: :block do |post| span(link_to(post.title, admin_post_path(post))) end end @@ -55,7 +55,7 @@ Feature: Index Blank Slate Given an index configuration of: """ ActiveAdmin.register Post do - index :as => :blog + index as: :blog end """ And I should see "There are no Posts yet. Create one" diff --git a/features/index/index_parameters.feature b/features/index/index_parameters.feature index 92021771040..9f7ad873138 100644 --- a/features/index/index_parameters.feature +++ b/features/index/index_parameters.feature @@ -4,7 +4,7 @@ Feature: Index Parameters Given an index configuration of: """ ActiveAdmin.register Post do - index :as => :table, :download_links => false + index as: :table, download_links: false end """ Given 31 posts exist @@ -19,7 +19,7 @@ Feature: Index Parameters Given an index configuration of: """ ActiveAdmin.register Post do - index :as => :table + index as: :table end """ Given 1 posts exist @@ -35,15 +35,15 @@ Feature: Index Parameters Given a configuration of: """ ActiveAdmin.application.namespace(:superadmin).download_links = false - ActiveAdmin.register AdminUser, :namespace => :superadmin + ActiveAdmin.register AdminUser, namespace: :superadmin """ Given an index configuration of: """ ActiveAdmin.register Post do - index :as => :table + index as: :table end - ActiveAdmin.register Post, :namespace => :superadmin do - index :as => :table + ActiveAdmin.register Post, namespace: :superadmin do + index as: :table end """ Given 1 posts exist @@ -58,15 +58,15 @@ Feature: Index Parameters Given a configuration of: """ ActiveAdmin.application.namespace(:superadmin).download_links = false - ActiveAdmin.register AdminUser, :namespace => :superadmin + ActiveAdmin.register AdminUser, namespace: :superadmin """ Given an index configuration of: """ ActiveAdmin.register Post do - index :as => :table + index as: :table end - ActiveAdmin.register Post, :namespace => :superadmin do - index :as => :table, :download_links => true + ActiveAdmin.register Post, namespace: :superadmin do + index as: :table, download_links: true end """ Given 1 posts exist diff --git a/features/index/index_scope_to.feature b/features/index/index_scope_to.feature index d3f2876998e..564f07a5e08 100644 --- a/features/index/index_scope_to.feature +++ b/features/index/index_scope_to.feature @@ -35,7 +35,7 @@ Feature: Index Scope To Given an index configuration of: """ ActiveAdmin.register Post do - scope_to :if => proc{ false } do + scope_to if: proc{ false } do User.find_by_first_name_and_last_name("John", "Doe") end end @@ -47,7 +47,7 @@ Feature: Index Scope To Given an index configuration of: """ ActiveAdmin.register Post do - scope_to :unless => proc{ true } do + scope_to unless: proc{ true } do User.find_by_first_name_and_last_name("John", "Doe") end end diff --git a/features/index/index_scopes.feature b/features/index/index_scopes.feature index 817a48ee24b..e851e0d6855 100644 --- a/features/index/index_scopes.feature +++ b/features/index/index_scopes.feature @@ -19,7 +19,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => true + scope :all, default: true end """ Then I should see the scope "All" selected @@ -31,7 +31,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => proc{ false } + scope :all, default: proc{ false } end """ Then I should see the scope "All" not selected @@ -43,7 +43,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => true + scope :all, default: true filter :title end """ @@ -56,8 +56,8 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => true - index :as => :table, :scope_count => false + scope :all, default: true + index as: :table, scope_count: false end """ Then I should see the scope "All" selected @@ -70,7 +70,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => true, :show_count => false + scope :all, default: true, show_count: false end """ Then I should see the scope "All" selected @@ -83,7 +83,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => true + scope :all, default: true scope :published do |posts| posts.where("published_date IS NOT NULL") end @@ -106,7 +106,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => true + scope :all, default: true scope :published do |posts| posts.where("published_date IS NOT NULL") end @@ -135,14 +135,14 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :if => proc { false } - scope "Shown", :if => proc { true } do |posts| + scope :all, if: proc { false } + scope "Shown", if: proc { true } do |posts| posts end - scope "Default", :default => true do |posts| + scope "Default", default: true do |posts| posts end - scope 'Today', :if => proc { false } do |posts| + scope 'Today', if: proc { false } do |posts| posts.where(["created_at > ? AND created_at < ?", ::Time.zone.now.beginning_of_day, ::Time.zone.now.end_of_day]) end end @@ -158,7 +158,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope 'Today', :default => true do |posts| + scope 'Today', default: true do |posts| posts.where(["created_at > ? AND created_at < ?", ::Time.zone.now.beginning_of_day, ::Time.zone.now.end_of_day]) end scope 'Tomorrow' do |posts| @@ -186,7 +186,7 @@ Feature: Index Scoping """ ActiveAdmin.register Post do scope_to :current_user - scope :all, :default => true + scope :all, default: true filter :title @@ -213,7 +213,7 @@ Feature: Index Scoping And an index configuration of: """ ActiveAdmin.register Post do - scope :all, :default => true + scope :all, default: true scope :published do |posts| posts.where("published_date IS NOT NULL") end diff --git a/features/index/page_title.feature b/features/index/page_title.feature index 7eca0e5db58..945c3086a4f 100644 --- a/features/index/page_title.feature +++ b/features/index/page_title.feature @@ -6,7 +6,7 @@ Feature: Index - Page Title Given an index configuration of: """ ActiveAdmin.register Post do - index :title => "Awesome Title" + index title: "Awesome Title" end """ Then I should see the page title "Awesome Title" @@ -15,7 +15,7 @@ Feature: Index - Page Title Given an index configuration of: """ ActiveAdmin.register Post do - index :title => proc{ 'Custom title from proc' } + index title: proc{ 'Custom title from proc' } end """ Then I should see the page title "Custom title from proc" @@ -24,7 +24,7 @@ Feature: Index - Page Title Given an index configuration of: """ ActiveAdmin.register Post do - index :title => proc{ "List of #{resource_class.model_name.plural}" } + index title: proc{ "List of #{resource_class.model_name.plural}" } end """ Then I should see the page title "List of posts" diff --git a/features/index/pagination.feature b/features/index/pagination.feature index e3484c5b65b..2236b72d53f 100644 --- a/features/index/pagination.feature +++ b/features/index/pagination.feature @@ -48,7 +48,7 @@ Feature: Index Pagination """ ActiveAdmin.register Post do config.per_page = 10 - index :pagination_total => false do + index pagination_total: false do end end """ diff --git a/features/index/switch_index_view.feature b/features/index/switch_index_view.feature index f06494a14fb..630ed4dfcee 100644 --- a/features/index/switch_index_view.feature +++ b/features/index/switch_index_view.feature @@ -9,10 +9,10 @@ Feature: Switch Index View And an index configuration of: """ ActiveAdmin.register Post do - index :as => :table do + index as: :table do column :title end - index :as => :block do |post| + index as: :block do |post| span(link_to(post.title, admin_post_path(post))) end end @@ -24,10 +24,10 @@ Feature: Switch Index View And an index configuration of: """ ActiveAdmin.register Post do - index :as => :block do |post| + index as: :block do |post| span(link_to(post.title, admin_post_path(post))) end - index :as => :table, :default => true do + index as: :table, default: true do column :title end end @@ -39,10 +39,10 @@ Feature: Switch Index View And an index configuration of: """ ActiveAdmin.register Post do - index :as => :block do |post| + index as: :block do |post| span(link_to(post.title, admin_post_path(post))) end - index :as => :table, :default => true do + index as: :table, default: true do column :title end end @@ -56,10 +56,10 @@ Feature: Switch Index View And an index configuration of: """ ActiveAdmin.register Post do - index :as => :block do |post| + index as: :block do |post| span(link_to(post.title, admin_post_path(post))) end - index :as => :table, :default => true do + index as: :table, default: true do column :title column :body end diff --git a/features/menu.feature b/features/menu.feature index 7cd4b3d7dbe..2c0f67ccc7c 100644 --- a/features/menu.feature +++ b/features/menu.feature @@ -17,7 +17,7 @@ Feature: Menu Given a configuration of: """ ActiveAdmin.register Post do - menu :label => "Articles" + menu label: "Articles" end """ When I am on the dashboard @@ -29,7 +29,7 @@ Feature: Menu """ ActiveAdmin.application.namespace :admin do |admin| admin.build_menu do |menu| - menu.add :label => "Custom Menu", :url => :admin_dashboard_path + menu.add label: "Custom Menu", url: :admin_dashboard_path end end """ @@ -43,7 +43,7 @@ Feature: Menu """ ActiveAdmin.register User ActiveAdmin.register Post do - menu :parent => 'User' + menu parent: 'User' end """ When I am on the dashboard diff --git a/features/new_page.feature b/features/new_page.feature index 57223e9114c..40bce0c550b 100644 --- a/features/new_page.feature +++ b/features/new_page.feature @@ -62,7 +62,7 @@ Feature: New Page Given "app/views/admin/posts/_form.html.erb" contains: """ <% url = @post.new_record? ? admin_posts_path : admin_post_path(@post) %> - <%= active_admin_form_for @post, :url => url do |f| + <%= active_admin_form_for @post, url: url do |f| f.inputs :title, :body f.actions end %> @@ -72,7 +72,7 @@ Feature: New Page ActiveAdmin.register Post do permit_params :custom_category_id, :author_id, :title, :body, :published_date, :starred if Rails::VERSION::MAJOR >= 4 - form :partial => "form" + form partial: "form" end """ Given I follow "New Post" diff --git a/features/registering_assets.feature b/features/registering_assets.feature index 5391e2538d7..ff126638bdf 100644 --- a/features/registering_assets.feature +++ b/features/registering_assets.feature @@ -18,7 +18,7 @@ Feature: Registering Assets Scenario: Registering a CSS file Given a configuration of: """ - ActiveAdmin.application.register_stylesheet "some-random-css.css", :media => :print + ActiveAdmin.application.register_stylesheet "some-random-css.css", media: :print ActiveAdmin.register Post """ When I am on the index page for posts diff --git a/features/registering_pages.feature b/features/registering_pages.feature index 7d4b32eab96..85e789c13a3 100644 --- a/features/registering_pages.feature +++ b/features/registering_pages.feature @@ -49,7 +49,7 @@ Feature: Registering Pages Given a configuration of: """ ActiveAdmin.register_page "Status" do - content :title => "Custom Page Title" do + content title: "Custom Page Title" do "I love chocolate." end end @@ -62,7 +62,7 @@ Feature: Registering Pages Given a configuration of: """ ActiveAdmin.register_page "Status" do - content :title => proc{ "Custom Page Title from Proc" } do + content title: proc{ "Custom Page Title from Proc" } do "I love chocolate." end end diff --git a/features/registering_resources.feature b/features/registering_resources.feature index 20d1bfc0cc8..094e612c897 100644 --- a/features/registering_resources.feature +++ b/features/registering_resources.feature @@ -22,7 +22,7 @@ Feature: Registering Resources Scenario: Registering a resource with another name Given a configuration of: """ - ActiveAdmin.register Post, :as => "My Post" + ActiveAdmin.register Post, as: "My Post" """ When I go to the dashboard Then I should see "My Posts" diff --git a/features/show/page_title.feature b/features/show/page_title.feature index 0f1dad67b97..517213d29bb 100644 --- a/features/show/page_title.feature +++ b/features/show/page_title.feature @@ -9,7 +9,7 @@ Feature: Show - Page Title Given a show configuration of: """ ActiveAdmin.register Post do - show :title => :title + show title: :title end """ Then I should see the page title "Hello World" @@ -18,7 +18,7 @@ Feature: Show - Page Title Given a show configuration of: """ ActiveAdmin.register Post do - show :title => "Title From String" + show title: "Title From String" end """ Then I should see the page title "Title From String" @@ -27,7 +27,7 @@ Feature: Show - Page Title Given a show configuration of: """ ActiveAdmin.register Post do - show :title => proc{|post| "Title: " + post.title } + show title: proc{|post| "Title: " + post.title } end """ Then I should see the page title "Title: Hello World" diff --git a/features/sidebar_sections.feature b/features/sidebar_sections.feature index ee4dafb52d8..1cbbb0cf8d9 100644 --- a/features/sidebar_sections.feature +++ b/features/sidebar_sections.feature @@ -34,7 +34,7 @@ Feature: Sidebar Sections Given a configuration of: """ ActiveAdmin.register Post do - sidebar :help, :only => :index do + sidebar :help, only: :index do "Need help? Email us at help@example.com" end end @@ -58,7 +58,7 @@ Feature: Sidebar Sections Given a configuration of: """ ActiveAdmin.register Post do - sidebar :help, :except => :index do + sidebar :help, except: :index do "Need help? Email us at help@example.com" end end @@ -80,7 +80,7 @@ Feature: Sidebar Sections Given a configuration of: """ ActiveAdmin.register Post do - sidebar :help, :only => :index, :if => proc{ current_active_admin_user.nil? } do + sidebar :help, only: :index, if: proc{ current_active_admin_user.nil? } do "Need help? Email us at help@example.com" end end @@ -106,7 +106,7 @@ Feature: Sidebar Sections end ActiveAdmin.register Post do controller { helper SidebarHelper } - sidebar :help, :only => :index, :if => :can_sidebar? do + sidebar :help, only: :index, if: :can_sidebar? do "Need help? Email us at help@example.com" end end @@ -128,7 +128,7 @@ Feature: Sidebar Sections Given a configuration of: """ ActiveAdmin.register Post do - sidebar :help, :only => :show, :if => proc{ !current_active_admin_user.nil? } do + sidebar :help, only: :show, if: proc{ !current_active_admin_user.nil? } do "Need help? Email us at help@example.com" end end @@ -190,7 +190,7 @@ Feature: Sidebar Sections Given a configuration of: """ ActiveAdmin.register Post do - sidebar :help, :partial => "custom_help_partial" + sidebar :help, partial: "custom_help_partial" end """ When I am on the index page for posts diff --git a/features/specifying_actions.feature b/features/specifying_actions.feature index 4bf8983b8bf..39c93b47a3e 100644 --- a/features/specifying_actions.feature +++ b/features/specifying_actions.feature @@ -23,7 +23,7 @@ Feature: Specifying Actions Given a configuration of: """ ActiveAdmin.register Post do - action_item(:import, :only => :index) do + action_item(:import, only: :index) do link_to('Import Posts', import_admin_posts_path) end @@ -43,7 +43,7 @@ Feature: Specifying Actions Given a configuration of: """ ActiveAdmin.register Post do - action_item(:review, :only => :show) do + action_item(:review, only: :show) do link_to('Review', review_admin_post_path) end @@ -69,7 +69,7 @@ Feature: Specifying Actions Given a configuration of: """ ActiveAdmin.register Post do - action_item(:review, :only => :show) do + action_item(:review, only: :show) do link_to('Review', review_admin_post_path) end diff --git a/lib/active_admin/batch_actions/views/batch_action_selector.rb b/lib/active_admin/batch_actions/views/batch_action_selector.rb index 3722194f75e..bfaf4cc1e12 100644 --- a/lib/active_admin/batch_actions/views/batch_action_selector.rb +++ b/lib/active_admin/batch_actions/views/batch_action_selector.rb @@ -15,7 +15,7 @@ def build(batch_actions) end # We don't want to wrap the action list (or any other children) in - # an unecessary div, so instead we just return the children + # an unnecessary div, so instead we just return the children def to_s children.to_s end diff --git a/lib/active_admin/views/components/dropdown_menu.rb b/lib/active_admin/views/components/dropdown_menu.rb index e87c9ac2775..3030355b31f 100644 --- a/lib/active_admin/views/components/dropdown_menu.rb +++ b/lib/active_admin/views/components/dropdown_menu.rb @@ -7,7 +7,7 @@ module Views # # dropdown_menu "Administration" do # item "Edit Details", edit_details_path - # item "Edit My Account", edit_my_acccount_path + # item "Edit My Account", edit_my_account_path # end # # This will create a button with the label "Administration" and @@ -58,7 +58,7 @@ def build_menu(options) menu_list = nil - div :class => 'dropdown_menu_list_wrapper' do + div class: 'dropdown_menu_list_wrapper' do menu_list = ul(options) end diff --git a/lib/generators/active_admin/devise/devise_generator.rb b/lib/generators/active_admin/devise/devise_generator.rb index bcc4f7cf79d..e662689ed02 100644 --- a/lib/generators/active_admin/devise/devise_generator.rb +++ b/lib/generators/active_admin/devise/devise_generator.rb @@ -12,8 +12,8 @@ class DeviseGenerator < Rails::Generators::NamedBase RESERVED_NAMES = [:active_admin_user] - class_option :default_user, :type => :boolean, :default => true, - :desc => "Should a default user be created inside the migration?" + class_option :default_user, type: :boolean, default: true, + desc: "Should a default user be created inside the migration?" def install_devise begin diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6312bf2f060..b15f7cd7bef 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -146,7 +146,7 @@ def with_translation(translation) # improve the performance of the specs suite by not logging anything # see http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/ -Rails.logger.level = 4 +Rails.logger.level = Logger::FATAL # Improves performance by forcing the garbage collector to run less often. unless ENV['DEFER_GC'] == '0' || ENV['DEFER_GC'] == 'false' diff --git a/spec/requests/default_namespace_spec.rb b/spec/requests/default_namespace_spec.rb index ec1dafbe902..e9d618742d0 100644 --- a/spec/requests/default_namespace_spec.rb +++ b/spec/requests/default_namespace_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Application, :type => :request do +describe ActiveAdmin::Application, type: :request do include Rails.application.routes.url_helpers diff --git a/spec/requests/stylesheets_spec.rb b/spec/requests/stylesheets_spec.rb index 00d0f5ff3bf..1fea493c1a9 100644 --- a/spec/requests/stylesheets_spec.rb +++ b/spec/requests/stylesheets_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "Stylesheets", :type => :request do +describe "Stylesheets", type: :request do require "sprockets" diff --git a/spec/support/templates/policies/application_policy.rb b/spec/support/templates/policies/application_policy.rb index 3912a49e151..152801007f0 100644 --- a/spec/support/templates/policies/application_policy.rb +++ b/spec/support/templates/policies/application_policy.rb @@ -11,7 +11,7 @@ def index? end def show? - scope.where(:id => record.id).exists? + scope.where(id: record.id).exists? end def new? diff --git a/spec/unit/resource_controller/decorators_spec.rb b/spec/unit/resource_controller/decorators_spec.rb index e9258366400..1fa822394bd 100644 --- a/spec/unit/resource_controller/decorators_spec.rb +++ b/spec/unit/resource_controller/decorators_spec.rb @@ -34,7 +34,7 @@ def self.name it "does not decorate when :decorate is set to false" do form = double - allow(form).to receive(:options).and_return(:decorate => false) + allow(form).to receive(:options).and_return(decorate: false) allow(active_admin_config).to receive(:get_page_presenter).and_return(form) is_expected.not_to be_kind_of(PostDecorator) end diff --git a/tasks/parallel_tests.rake b/tasks/parallel_tests.rake index 78a8a5ade3b..6940b43de8d 100644 --- a/tasks/parallel_tests.rake +++ b/tasks/parallel_tests.rake @@ -2,7 +2,7 @@ require 'parallel' require 'shellwords' desc "Run the full suite using parallel_tests to run on multiple cores" -task :parallel_tests => ['parallel:setup_parallel_tests', 'parallel:spec', 'parallel:features', 'cucumber:class_reloading'] +task parallel_tests: ['parallel:setup_parallel_tests', 'parallel:spec', 'parallel:features', 'cucumber:class_reloading'] namespace :parallel do @@ -43,7 +43,7 @@ namespace :parallel do end desc "Run the specs in parallel" - task :spec => :setup_parallel_tests do + task spec: :setup_parallel_tests do run_in_parallel "parallel_rspec spec/" end @@ -59,7 +59,7 @@ namespace :parallel do end desc "Run the cucumber features in parallel" - task :features => :setup_parallel_tests do + task features: :setup_parallel_tests do run_in_parallel "parallel_cucumber features/" end diff --git a/tasks/test.rake b/tasks/test.rake index a5c7f1c35d4..f0d2ed27490 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -45,7 +45,7 @@ namespace :test do end desc "Alias for major_supported_rails" - task :all => :major_supported_rails + task all: :major_supported_rails end From 4ff2ecdf7e644236e42f00ad966bf8178fff8b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Sep 2016 19:27:20 -0300 Subject: [PATCH 0215/3836] Require `rake` in Gemfile just like the other deps --- Gemfile | 2 +- Rakefile | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 84c653207eb..a28cba305d2 100644 --- a/Gemfile +++ b/Gemfile @@ -35,7 +35,7 @@ gem 'draper', rails_major == '5' ? '> 3.x' : '~> 2.1' gem 'pundit' # Utility gems used in both development & test environments -gem 'rake', require: false +gem 'rake' gem 'parallel_tests', '< 2.10' #2.10 requires ruby '>= 2.0.0' # Debugging diff --git a/Rakefile b/Rakefile index dcb8aa60b9f..c7aa38bd050 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,4 @@ require 'bundler' -require 'rake' Bundler.setup Bundler::GemHelper.install_tasks From a6cfc12f28fca282d6bfbed3032adc8aba75b66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Sep 2016 19:29:02 -0300 Subject: [PATCH 0216/3836] Simplify Rakefile Use equivalent requires. --- Rakefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index c7aa38bd050..1fe83932c7c 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,5 @@ -require 'bundler' -Bundler.setup -Bundler::GemHelper.install_tasks +require 'bundler/setup' +require 'bundler/gem_tasks' def cmd(command) puts command From 67ab58c725341768b9cce8c7faa86ffd6df900d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Sep 2016 19:45:51 -0300 Subject: [PATCH 0217/3836] Use Travis CI built-in caching --- .travis.yml | 10 ++--- script/travis_cache | 107 -------------------------------------------- 2 files changed, 4 insertions(+), 113 deletions(-) delete mode 100755 script/travis_cache diff --git a/.travis.yml b/.travis.yml index 7743bd50dac..96bd0db1829 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,12 @@ language: ruby sudo: false -install: - - ./script/travis_cache download_bundle +bundler_args: --without development +cache: bundler +before_install: - gem update --system # use the very latest Rubygems - gem install bundler # use the very latest Bundler - - bundle install --without development --path=./bundle - - bundle clean # delete now-outdated gems - - ./script/travis_cache download_app +before_script: - bundle exec rake setup - - ./script/travis_cache upload script: - bundle exec rake test rvm: diff --git a/script/travis_cache b/script/travis_cache deleted file mode 100755 index caec5a6226f..00000000000 --- a/script/travis_cache +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env ruby - -require 'base64' -require 'digest' -require 'openssl' -require 'shellwords' - -prefix = "ruby_#{RUBY_VERSION}-rails_#{ENV.fetch 'RAILS'}-" -BUNDLE = prefix + 'bundle' -APP = prefix + 'app' - -def download_bundle - s3 :save, file: "#{BUNDLE}.sha2", as: "remote-#{BUNDLE}.sha2" - s3 :save, file: "#{BUNDLE}.tgz", as: "remote-#{BUNDLE}.tgz", untar: true -end - -def download_app - # Force test app re-build if dependencies were updated - unless digest_changed? 'Gemfile.lock', "remote-#{BUNDLE}.sha2", "#{BUNDLE}.sha2" - s3 :save, file: "#{APP}.sha2", as: "remote-#{APP}.sha2" - # Force test app re-build if spec/support changed - unless digest_changed? 'spec/support', "remote-#{APP}.sha2", "#{APP}.sha2" - s3 :save, file: "#{APP}.tgz", as: "remote-#{APP}.tgz", untar: true - end - end -end - -def upload - unless ID && SECRET - puts "S3 credentials missing" - return - end - - [ ['Gemfile.lock', BUNDLE, 'bundle'], - ['spec/support', APP, 'spec/rails'] - ].each do |to_check, name, to_save| - puts "=> Checking #{to_check} for changes" - if ret = digest_changed?(to_check, "remote-#{name}.sha2", "#{name}.sha2") - puts " => Changes found: #{ret[:old]} -> #{ret[:new]}" - - puts " => Creating an archive" - `tar -cjf #{name}.tgz #{to_save}` - - puts " => Uploading a new archive" - s3 :upload, file: "#{name}.tgz" - s3 :upload, file: "#{name}.sha2" - else - puts " => There were no changes, doing nothing" - end - end -end - -def digest_changed?(to_check, old_digest_file, new_digest_file) - if File.exists? new_digest_file - digest = File.read new_digest_file - else - # Supports a single file, as well as a folder - files = Dir[to_check, "#{to_check}/**/*"].reject{ |f| File.directory? f } - content = files.sort!.map{ |f| File.read f }.join - digest = Digest::SHA2.hexdigest content - File.write new_digest_file, digest - end - - old_digest = File.read old_digest_file if File.exists? old_digest_file - - {old: old_digest, new: digest} if digest != old_digest -end - -def sign(secret, to_sign) - Base64.strict_encode64 OpenSSL::HMAC.digest OpenSSL::Digest::SHA1.new, secret, to_sign -end - -ID = ENV['AWS_S3_ID'] -SECRET = ENV['AWS_S3_SECRET'] -URL = 'https://s3.amazonaws.com/ActiveAdmin' - -# s3 :list -# s3 :upload, file: 'foo' -# s3 :find, file: 'foo' -# s3 :save, file: 'foo', as: 'bar' -# s3 :save, file: 'foo', untar: true -def s3(action, options = {}) - verb = {list: :get, upload: :put, find: :get, save: :get}.fetch action - file = options.fetch(:file) unless action == :list - extra_arg = case action - when :upload then "-T #{file}" - when :save then options[:as] ? "-o #{options[:as]}" : '-O' - end - do_after = "&& tar -xf #{options[:as] || file}" if options[:untar] - - if ID && SECRET - now = Time.now.strftime "%a, %d %b %Y %H:%M:%S %z" - signature = sign SECRET, "#{verb.upcase}\n\n\n#{now}\n/ActiveAdmin/#{file}" - headers = ["Authorization: AWS #{ID}:#{signature}", "Date: #{now}"].map do |h| - "-H #{Shellwords.escape h}" - end.join ' ' - end - - output = `curl -f #{headers} #{extra_arg} #{URL}/#{file} #{do_after}` - [$?.success?, output] -end - -if %w[download_bundle download_app upload].include? ARGV[0] - send ARGV[0] -else - raise "unexpected argument(s): #{ARGV}" -end From 7addcf6329a119dc718454ebb56d394121d254dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 23 Jan 2017 16:32:17 -0200 Subject: [PATCH 0218/3836] Start jruby first in CI Since it's the slowest, this will save us some impatience. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 96bd0db1829..c11282f15fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,10 @@ before_script: script: - bundle exec rake test rvm: + - jruby-9.1.6.0 - 1.9.3 - 2.2.6 - 2.3.3 - - jruby-9.1.6.0 env: matrix: - RAILS=3.2.22 From 3033ba694b6a39555dce3d3553c777e2bcc4ad85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 10:10:10 -0300 Subject: [PATCH 0219/3836] Reformat Travis config file Just for visual pleasure :) --- .travis.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.travis.yml b/.travis.yml index c11282f15fb..3b41b3c67f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,29 @@ +--- + language: ruby + sudo: false + bundler_args: --without development + cache: bundler + before_install: - gem update --system # use the very latest Rubygems - gem install bundler # use the very latest Bundler + before_script: - bundle exec rake setup + script: - bundle exec rake test + rvm: - jruby-9.1.6.0 - 1.9.3 - 2.2.6 - 2.3.3 + env: matrix: - RAILS=3.2.22 @@ -21,22 +31,29 @@ env: - RAILS=4.1.16 - RAILS=4.2.7.1 - RAILS=5.0.1 + global: - JRUBY_OPTS="-J-Xmx1024m --debug" + matrix: fast_finish: true + exclude: - rvm: 1.9.3 env: RAILS=5.0.1 + allow_failures: - rvm: jruby-9.1.6.0 env: RAILS=5.0.1 + notifications: irc: channels: - irc.freenode.org#activeadmin + on_success: change on_failure: always skip_join: true + template: - "(%{branch}/%{commit} by %{author}): %{message} (%{build_url})" From 482734534adb69ca4eb08c889bfb810708f3ac8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 21 Jan 2017 11:34:49 -0200 Subject: [PATCH 0220/3836] Lock bundler to a known working version --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3b41b3c67f5..17ed6945a9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,8 @@ cache: bundler before_install: - gem update --system # use the very latest Rubygems - - gem install bundler # use the very latest Bundler + - rvm @global do gem uninstall bundler -a -x + - rvm @global do gem install bundler -v 1.14.2 # latest version known to work before_script: - bundle exec rake setup From f61d9cb816e4cd443a03a68ccb967ef840d49452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 24 Jan 2017 14:15:12 -0200 Subject: [PATCH 0221/3836] Don't recommend hard force-pushes --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4e10e863e36..68546b6b0d1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -140,7 +140,7 @@ but here's the suggested workflow: ```sh git checkout 325-add-japanese-translations git pull --rebase upstream master -git push -f 325-add-japanese-translations +git push --force-with-lease 325-add-japanese-translations ``` ### 9. Merging a PR (maintainers only) From 701fd27429e1b9629317a8aba79d6138123600d4 Mon Sep 17 00:00:00 2001 From: Bernardo Amorim Date: Sun, 13 Jul 2014 17:24:34 -0300 Subject: [PATCH 0222/3836] Added nested belongs_to functionality. --- features/belongs_to.feature | 18 ++++++++++ features/support/paths.rb | 3 ++ lib/active_admin/base_controller/menu.rb | 2 +- lib/active_admin/resource.rb | 9 ++--- lib/active_admin/resource/routes.rb | 26 +++++++-------- lib/active_admin/router.rb | 23 +++++++------ .../view_helpers/breadcrumb_helper.rb | 7 ++-- spec/support/rails_template.rb | 6 ++++ spec/unit/belongs_to_spec.rb | 2 +- spec/unit/resource/routes_spec.rb | 33 +++++++++++++++++-- spec/unit/resource_spec.rb | 4 +-- spec/unit/routing_spec.rb | 25 ++++++++++++++ spec/unit/view_helpers/breadcrumbs_spec.rb | 4 +-- 13 files changed, 124 insertions(+), 38 deletions(-) diff --git a/features/belongs_to.feature b/features/belongs_to.feature index ab5f5f06edc..acc4f0e9c74 100644 --- a/features/belongs_to.feature +++ b/features/belongs_to.feature @@ -52,6 +52,24 @@ Feature: Belongs To When I follow "Posts" Then the "Posts" tab should be selected + Scenario: When the belongs to is nested + Given a configuration of: + """ + ActiveAdmin.register User + ActiveAdmin.register Post do + belongs_to :user + end + ActiveAdmin.register Tagging do + belongs_to :user + belongs_to :post + end + """ + When I go to the last author's last post's taggings + Then I should see a link to "Users" in the breadcrumb + And I should see a link to "Jane Doe" in the breadcrumb + And I should see a link to "Posts" in the breadcrumb + And I should see a link to "Hello World" in the breadcrumb + Scenario: Displaying belongs to resources in main menu Given a configuration of: """ diff --git a/features/support/paths.rb b/features/support/paths.rb index 42740996a94..8425987a722 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -48,6 +48,9 @@ def path_to(page_name) when /^the last post's show page$/ admin_post_path(Post.last) + when /^the last author's last post's taggings$/ + admin_user_post_taggings_path(User.last, Post.where(author_id: User.last.id).last) + when /^the last post's edit page$/ edit_admin_post_path(Post.last) diff --git a/lib/active_admin/base_controller/menu.rb b/lib/active_admin/base_controller/menu.rb index 07c3d37b208..7303f0b21da 100644 --- a/lib/active_admin/base_controller/menu.rb +++ b/lib/active_admin/base_controller/menu.rb @@ -22,7 +22,7 @@ def current_menu # Get's called through a before filter def set_current_tab @current_tab = if current_menu && active_admin_config.belongs_to? && parent? - parent_item = active_admin_config.belongs_to_config.target.menu_item + parent_item = active_admin_config.belongs_to_config.first.target.menu_item if current_menu.include? parent_item parent_item else diff --git a/lib/active_admin/resource.rb b/lib/active_admin/resource.rb index 363a085bb64..8567825d7c3 100644 --- a/lib/active_admin/resource.rb +++ b/lib/active_admin/resource.rb @@ -120,18 +120,19 @@ def defined_actions end def belongs_to(target, options = {}) - @belongs_to = Resource::BelongsTo.new(self, target, options) - self.navigation_menu_name = target unless @belongs_to.optional? + this_belongs_to = Resource::BelongsTo.new(self, target, options) + self.navigation_menu_name = target unless this_belongs_to.optional? + belongs_to_config << this_belongs_to controller.send :belongs_to, target, options.dup end def belongs_to_config - @belongs_to + @belongs_to ||= [] end # Do we belong to another resource? def belongs_to? - !!belongs_to_config + belongs_to_config.length > 0 end # The csv builder for this resource diff --git a/lib/active_admin/resource/routes.rb b/lib/active_admin/resource/routes.rb index b5ec172796f..9061f98de66 100644 --- a/lib/active_admin/resource/routes.rb +++ b/lib/active_admin/resource/routes.rb @@ -75,7 +75,7 @@ def route_name(resource_path_name, options = {}) route << options[:action] # "edit" or "new" route << resource.route_prefix # "admin" - route << belongs_to_name if nested? # "category" + route += belongs_to_names route << resource_path_name # "posts" or "post" route << suffix # "path" or "index path" @@ -85,25 +85,25 @@ def route_name(resource_path_name, options = {}) # @return params to pass to instance path def route_instance_params(instance) - if nested? - [instance.public_send(belongs_to_name).to_param, instance.to_param] - else - instance.to_param - end + belongs_to_names.reverse.reduce([instance]) do |arr,name| + arr + [arr.last.public_send(name)] + end.map{|i| i.to_param }.reverse end def route_collection_params(params) - if nested? - params[:"#{belongs_to_name}_id"] - end + belongs_to_names.map{|name| params[:"#{name}_id"]} end - def nested? - resource.belongs_to? && resource.belongs_to_config.required? + def belongs_to_names + required_belongs_to.map{|bc| bc.target.resource_name.singular } end - def belongs_to_name - resource.belongs_to_config.target.resource_name.singular if nested? + def required_belongs_to + if resource.belongs_to? + resource.belongs_to_config.select{|bc| bc.required?} + else + [] + end end def routes diff --git a/lib/active_admin/router.rb b/lib/active_admin/router.rb index 9d40d27b236..7ec2eddf667 100644 --- a/lib/active_admin/router.rb +++ b/lib/active_admin/router.rb @@ -38,19 +38,22 @@ def define_resource_routes(router) resources.each do |config| routes = aa_router.resource_routes(config) - # Add in the parent if it exists - if config.belongs_to? - belongs_to = routes - routes = Proc.new do - # If it's optional, make the normal resource routes - instance_exec &belongs_to if config.belongs_to_config.optional? + # Add in the parents for each, starting from the first(out) to the last(in) exists + + if(config.belongs_to?) + belongs_to = config.belongs_to_config.reverse.reduce(routes) do |r,btc| + Proc.new do + # If it's optional, make the normal resource routes + instance_exec &r if btc.optional? - # Make the nested belongs_to routes - # :only is set to nothing so that we don't clobber any existing routes on the resource - resources config.belongs_to_config.target.resource_name.plural, only: [] do - instance_exec &belongs_to + # Make the nested belongs_to routes + # :only is set to nothing so that we don't clobber any existing routes on the resource + resources btc.target.resource_name.plural, only: [] do + instance_exec &r + end end end + routes = belongs_to end # Add on the namespace if required diff --git a/lib/active_admin/view_helpers/breadcrumb_helper.rb b/lib/active_admin/view_helpers/breadcrumb_helper.rb index 3d3e01fd5a4..e560b899e32 100644 --- a/lib/active_admin/view_helpers/breadcrumb_helper.rb +++ b/lib/active_admin/view_helpers/breadcrumb_helper.rb @@ -13,9 +13,10 @@ def breadcrumb_links(path = request.path) # 2. try using the model name translation # 3. default to calling `titlecase` on the URL fragment if part =~ /\A(\d+|[a-f0-9]{24})\z/ && parts[index-1] - parent = active_admin_config.belongs_to_config.try :target - config = parent && parent.resource_name.route_key == parts[index-1] ? parent : active_admin_config - name = display_name config.find_resource part + config = active_admin_config.belongs_to_config.map(&:target).select do |parent| + parent.resource_name.route_key == parts[index-1] + end.first || active_admin_config + name = display_name config.find_resource part end name ||= I18n.t "activerecord.models.#{part.singularize}", count: ::ActiveAdmin::Helpers::I18n::PLURAL_MANY_COUNT, default: part.titlecase diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 226f41cde8e..882ba4b978f 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -21,6 +21,12 @@ class Post < ActiveRecord::Base RUBY copy_file File.expand_path('../templates/post_decorator.rb', __FILE__), 'app/models/post_decorator.rb' +generate :model, "post_comment message:string post_id:integer" +inject_into_file 'app/models/post_comment.rb', %q{ + belongs_to :post + attr_accessible :message, :post unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes + }, after: 'class PostComment < ActiveRecord::Base' + generate :model, 'blog/post title:string body:text published_date:date author_id:integer ' + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' create_file 'app/models/blog/post.rb', <<-RUBY.strip_heredoc, force: true diff --git a/spec/unit/belongs_to_spec.rb b/spec/unit/belongs_to_spec.rb index 96cc12ab701..d675c67b5af 100644 --- a/spec/unit/belongs_to_spec.rb +++ b/spec/unit/belongs_to_spec.rb @@ -4,7 +4,7 @@ let(:user_config){ ActiveAdmin.register User } let(:post_config){ ActiveAdmin.register Post do belongs_to :user end } - let(:belongs_to){ post_config.belongs_to_config } + let(:belongs_to){ post_config.belongs_to_config.first } it "should have an owner" do expect(belongs_to.owner).to eq post_config diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index a5957bf7f4b..0ebfb6c7ae5 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -1,9 +1,9 @@ -require 'rails_helper' +require 'rails_helper' module ActiveAdmin describe Resource::Routes do - after :all do + after do load_defaults! reload_routes! end @@ -72,6 +72,35 @@ class ::News; def self.has_many(*); end end expect(config.route_instance_path(post)).to eq "/admin/categories/1/posts/3" end end + + context "when the resources belongs to two other resources" do + let! :config do + ActiveAdmin.register Tagging do + belongs_to :category + belongs_to :post + end + end + + let :tagging do + Tagging.new do |t| + t.id = 4 + t.post = Post.new do |p| + p.id = 3 + p.category = Category.new{ |c| c.id = 1 } + end + end + end + + before{ reload_routes! } + + it "should nest the collection path" do + expect(config.route_collection_path(category_id: 1, post_id: 3)).to eq "/admin/categories/1/posts/3/taggings" + end + + it "should nest the instance path" do + expect(config.route_instance_path(tagging)).to eq "/admin/categories/1/posts/3/taggings/4" + end + end end end end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index a9b8e794222..27e3a75551b 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -80,9 +80,9 @@ def config(options = {}) describe "#belongs_to" do it "should build a belongs to configuration" do - expect(config.belongs_to_config).to eq nil + expect(config.belongs_to_config.length).to eq 0 config.belongs_to :posts - expect(config.belongs_to_config).to_not eq nil + expect(config.belongs_to_config.length).to eq 1 end it "should set the target menu to the belongs to target" do diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index be6ba701c4e..9af60e1c083 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -169,6 +169,31 @@ end end + describe "nested belongs to resource" do + before do + ActiveAdmin.register(Tagging) do + belongs_to :user, optional: true + belongs_to :post + end + reload_routes! + end + it "should route the nested index path" do + expect(admin_user_post_taggings_path(1,2)).to eq "/admin/users/1/posts/2/taggings" + end + + it "should route the nested show path" do + expect(admin_user_post_tagging_path(1,2,3)).to eq "/admin/users/1/posts/2/taggings/3" + end + + it "should route the nested skipping optional index path" do + expect(admin_post_taggings_path(1)).to eq "/admin/posts/1/taggings" + end + + it "should route the nested skipping optional show path" do + expect(admin_post_tagging_path(1,2)).to eq "/admin/posts/1/taggings/2" + end + end + describe "page" do context "when default namespace" do before(:each) do diff --git a/spec/unit/view_helpers/breadcrumbs_spec.rb b/spec/unit/view_helpers/breadcrumbs_spec.rb index e83fc9f1e3f..59660b9819a 100644 --- a/spec/unit/view_helpers/breadcrumbs_spec.rb +++ b/spec/unit/view_helpers/breadcrumbs_spec.rb @@ -16,7 +16,7 @@ def link_to(name, url); {name: name, path: url}; end defined_actions: actions } let(:post) { double display_name: 'Hello World' } let(:post_config) { double find_resource: post, resource_name: double(route_key: 'posts'), - defined_actions: actions, belongs_to_config: double(target: user_config) } + defined_actions: actions, belongs_to_config: [double(target: user_config)] } let :active_admin_config do post_config @@ -193,7 +193,7 @@ def link_to(name, url); {name: name, path: url}; end context "when the 'show' action is disabled" do let(:post_config) { double find_resource: post, resource_name: double(route_key: 'posts'), defined_actions: actions - [:show], # this is the change - belongs_to_config: double(target: user_config) } + belongs_to_config: [double(target: user_config)] } let(:path) { "/admin/posts/1/edit" } From 2c1862dcb79311d2c7cf2dcda14d75daa2e9cedc Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Tue, 24 Jan 2017 11:30:16 +0200 Subject: [PATCH 0223/3836] fixes #4342, fixed active filters for rails 4.2 --- lib/active_admin/filters/active.rb | 10 +++++++++- spec/unit/filters/active_spec.rb | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 spec/unit/filters/active_spec.rb diff --git a/lib/active_admin/filters/active.rb b/lib/active_admin/filters/active.rb index c0d58dd8b3d..1b7d47d706d 100644 --- a/lib/active_admin/filters/active.rb +++ b/lib/active_admin/filters/active.rb @@ -8,13 +8,21 @@ class Active def initialize(resource_class, params) @resource_class = resource_class - @params = params.respond_to?(:to_unsafe_h) ? params.to_unsafe_h : params + @params = normalize_params(params) @scope = humanize_scope @filters = build_filters end private + def normalize_params(params) + if params.is_a?(HashWithIndifferentAccess) + params + else + params.to_unsafe_h + end + end + def build_filters filters = @params[:q] || [] filters.map{ |param| Humanized.new(param) } diff --git a/spec/unit/filters/active_spec.rb b/spec/unit/filters/active_spec.rb new file mode 100644 index 00000000000..1469fd01d3a --- /dev/null +++ b/spec/unit/filters/active_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +describe ActiveAdmin::Filters::Active do + subject { described_class.new(Post, params) } + let(:params_klass) do + if defined? ::ActionController::Parameters + ::ActionController::Parameters + else + HashWithIndifferentAccess #remove this when drop rails 3 support + end + end + + let(:params) do + params_klass.new(q: {author_id_eq: 1}) + end + + it 'should have filters' do + expect(subject.filters.size).to eq(1) + end + +end \ No newline at end of file From 2cc0caa528d3b5ca6f4e196c2ec4b5e11de09ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Sep 2016 17:32:53 -0300 Subject: [PATCH 0224/3836] Fix some error messages before running cucumber ``` rails aborted! ActiveRecord::NoEnvironmentInSchemaError: Environment data not found in the schema. To resolve this issue, run: bin/rails db:environment:set RAILS_ENV=test ``` --- spec/support/rails_template.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 882ba4b978f..24bace099ad 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -129,6 +129,10 @@ class Tagging < ActiveRecord::Base config.action_mailer.default_url_options = {host: 'example.com'} config.assets.digest = false + if ActiveAdmin::Dependency.rails? '>= 4.1.0' + config.active_record.maintain_test_schema = false + end + RUBY # Add our local Active Admin to the load path @@ -169,7 +173,7 @@ class Tagging < ActiveRecord::Base # https://github.com/plataformatec/devise/issues/2554 gsub_file 'config/initializers/devise.rb', /# config.secret_key =/, 'config.secret_key =' -rake 'db:migrate' +rake 'db:drop db:create db:migrate', env: ENV['RAILS_ENV'] || 'development' if ENV['INSTALL_PARALLEL'] inject_into_file 'config/database.yml', "<%= ENV['TEST_ENV_NUMBER'] %>", after: 'test.sqlite3' From c1e3bbe2ebd82bab3c1e1b190da3e56c0d2e312c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 11:53:44 -0300 Subject: [PATCH 0225/3836] Fix warnings in latest version of bundler ``` The git source `git://github.com/rails/sass-rails.git` uses the `git` protocol, which transmits data without encryption. Disable this warning with `bundle config git.allow_insecure true`, or switch to the `https` protocol to keep your data secure. The git source `git://github.com/activeadmin/inherited_resources.git` uses the `git` protocol, which transmits data without encryption. Disable this warning with `bundle config git.allow_insecure true`, or switch to the `https` protocol to keep your data secure. The git source `git://github.com/activerecord-hackery/ransack.git` uses the `git` protocol, which transmits data without encryption. Disable this warning with `bundle config git.allow_insecure true`, or switch to the `https` protocol to keep your data secure. ``` --- Gemfile | 6 +++--- README.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index a28cba305d2..fae4cc197bf 100644 --- a/Gemfile +++ b/Gemfile @@ -15,9 +15,9 @@ gem 'test-unit', '~> 3.0' if rails_major == '3' if rails_major == '5' # Note: when updating this list, be sure to also update the README - gem 'sass-rails', github: 'rails/sass-rails' - gem 'inherited_resources', github: 'activeadmin/inherited_resources' - gem 'ransack', github: 'activerecord-hackery/ransack' + gem 'sass-rails', git: 'https://github.com/rails/sass-rails' + gem 'inherited_resources', git: 'https://github.com/activeadmin/inherited_resources' + gem 'ransack', git: 'https://github.com/activerecord-hackery/ransack' end platform :ruby_19 do # Remove this block when we drop support for Ruby 1.9 diff --git a/README.md b/README.md index ae96d466fce..ccea00e7119 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ which as far as dependencies, moves us from meta_search to Ransack and adds Rail You can get it by tracking master: ```ruby -gem 'activeadmin', github: 'activeadmin' +gem 'activeadmin', git: 'https://github.com/activeadmin/activeadmin' ``` Or you can using rubygems: @@ -32,7 +32,7 @@ gem 'activeadmin', '~> 1.0.0.pre4' Active Admin master has preliminary support for Rails 5. To give it a try, these Gemfile changes may be needed: ```ruby -gem 'inherited_resources', github: 'activeadmin/inherited_resources' +gem 'inherited_resources', git: 'https://github.com/activeadmin/inherited_resources' ``` ### 0.6.x @@ -42,7 +42,7 @@ still be maintained, and we will backport bug fixes into future 0.6.x releases. to have to wait for a release, you can track the branch instead: ```ruby -gem 'activeadmin', github: 'activeadmin', branch: '0-6-stable' +gem 'activeadmin', git: 'https://github.com/activeadmin/activeadmin', branch: '0-6-stable' ``` ## Documentation From 42b6056bf87884e7fc38fe8b0c31637ec3f36299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 23:13:04 -0300 Subject: [PATCH 0226/3836] Unlock phantomjs version This way we can fix the warning ``` You're running an old version of PhantomJS, update to >= 2.1.1 for a better experience. ``` and, I guess, have a better experience. Also, make sure the latest version is also used in Travis. --- .travis.yml | 1 + Gemfile | 1 - script/install_phantomjs.sh | 10 ++++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 script/install_phantomjs.sh diff --git a/.travis.yml b/.travis.yml index 17ed6945a9d..e684e11ac20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ bundler_args: --without development cache: bundler before_install: + - source script/install_phantomjs.sh - gem update --system # use the very latest Rubygems - rvm @global do gem uninstall bundler -a -x - rvm @global do gem install bundler -v 1.14.2 # latest version known to work diff --git a/Gemfile b/Gemfile index fae4cc197bf..f81cefc44f7 100644 --- a/Gemfile +++ b/Gemfile @@ -74,7 +74,6 @@ group :test do gem 'guard-rspec', require: false gem 'listen', '~> 2.7', platforms: [:ruby_19, :jruby] gem 'jasmine' - gem 'phantomjs', '1.9.8.0' # Same version as Travis CI's pre-installed version gem 'jslint_on_rails' gem 'launchy' gem 'rails-i18n' # Provides default i18n for many languages diff --git a/script/install_phantomjs.sh b/script/install_phantomjs.sh new file mode 100644 index 00000000000..8a4d442e120 --- /dev/null +++ b/script/install_phantomjs.sh @@ -0,0 +1,10 @@ +VERSION=2.1.1 +BASENAME=phantomjs-$VERSION-linux-x86_64 +FULLNAME=$BASENAME.tar.bz2 +DOWNLOAD_BASE_URI=https://github.com/Medium/phantomjs +DOWNLOAD_URI=$DOWNLOAD_BASE_URI/releases/download/v$VERSION/$FULLNAME + +export PATH=$PWD/.phantomjs/$BASENAME/bin:$PATH +mkdir -p .phantomjs +wget --quiet $DOWNLOAD_URI -O .phantomjs/$FULLNAME +tar -xvf .phantomjs/$FULLNAME -C .phantomjs $BASENAME/bin/phantomjs From d5f7b22d042905ba7b2db26d079545ac8ed61aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Sep 2016 20:59:01 -0300 Subject: [PATCH 0227/3836] `File.exists?` is deprecated --- lib/generators/active_admin/devise/devise_generator.rb | 2 +- script/local | 4 ++-- spec/unit/generators/install_spec.rb | 8 ++++---- tasks/parallel_tests.rake | 2 +- tasks/test.rake | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/generators/active_admin/devise/devise_generator.rb b/lib/generators/active_admin/devise/devise_generator.rb index e662689ed02..1de499174e0 100644 --- a/lib/generators/active_admin/devise/devise_generator.rb +++ b/lib/generators/active_admin/devise/devise_generator.rb @@ -24,7 +24,7 @@ def install_devise require 'devise' - if File.exists?(File.join(destination_root, "config", "initializers", "devise.rb")) + if File.exist?(File.join(destination_root, "config", "initializers", "devise.rb")) log :generate, "No need to install devise, already done." else log :generate, "devise:install" diff --git a/script/local b/script/local index 75bc3dd7143..4d4e07c38bf 100755 --- a/script/local +++ b/script/local @@ -26,10 +26,10 @@ dir = ".test-rails-apps" path = "#{dir}/test-rails-app-#{rails_version}" # Ensure .test-rails-apps is created -system "mkdir #{dir}" unless File.exists?(dir) +system "mkdir #{dir}" unless File.exist?(dir) # Create the sample rails app if it doesn't already exist -unless File.exists? path +unless File.exist? path args = %w[ -m\ spec/support/rails_template_with_data.rb --skip-gemfile diff --git a/spec/unit/generators/install_spec.rb b/spec/unit/generators/install_spec.rb index 6b170a31a62..dc0d82b83c4 100644 --- a/spec/unit/generators/install_spec.rb +++ b/spec/unit/generators/install_spec.rb @@ -5,19 +5,19 @@ it "active_admin.scss" do path = Rails.root + "app/assets/stylesheets/active_admin.scss" - expect(File.exists? path).to eq true + expect(File.exist? path).to eq true end it "active_admin.js.coffee" do - expect(File.exists?(Rails.root + "app/assets/javascripts/active_admin.js.coffee")).to eq true + expect(File.exist?(Rails.root + "app/assets/javascripts/active_admin.js.coffee")).to eq true end it "the dashboard" do - expect(File.exists?(Rails.root + "app/admin/dashboard.rb")).to eq true + expect(File.exist?(Rails.root + "app/admin/dashboard.rb")).to eq true end it "the initializer" do - expect(File.exists?(Rails.root + "config/initializers/active_admin.rb")).to eq true + expect(File.exist?(Rails.root + "config/initializers/active_admin.rb")).to eq true end end diff --git a/tasks/parallel_tests.rake b/tasks/parallel_tests.rake index 6940b43de8d..9ce867acd07 100644 --- a/tasks/parallel_tests.rake +++ b/tasks/parallel_tests.rake @@ -20,7 +20,7 @@ namespace :parallel do def parallel_tests_setup? require 'rails/version' database_config = File.join "spec", "rails", "rails-#{Rails::VERSION::STRING}", "config", "database.yml" - File.exists?(database_config) && File.read(database_config).include?("TEST_ENV_NUMBER") + File.exist?(database_config) && File.read(database_config).include?("TEST_ENV_NUMBER") end desc "Setup parallel_tests DBs" diff --git a/tasks/test.rake b/tasks/test.rake index f0d2ed27490..d65ff4a716e 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,7 +1,7 @@ desc "Creates a test rails app for the specs to run against" task :setup, :parallel do |t, opts| require 'rails/version' - if File.exists? dir = "spec/rails/rails-#{Shellwords.escape detect_rails_version}" + if File.exist? dir = "spec/rails/rails-#{Shellwords.escape detect_rails_version}" puts "test app #{dir} already exists; skipping" else system 'mkdir -p spec/rails' From d49bcc1f5676d23ac486c2371e9862b2870a8455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 00:13:25 -0300 Subject: [PATCH 0228/3836] Make Hound happy --- .../active_admin/devise/devise_generator.rb | 5 ++++- spec/support/rails_template.rb | 2 +- spec/unit/generators/install_spec.rb | 15 +++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/generators/active_admin/devise/devise_generator.rb b/lib/generators/active_admin/devise/devise_generator.rb index 1de499174e0..2339b008d98 100644 --- a/lib/generators/active_admin/devise/devise_generator.rb +++ b/lib/generators/active_admin/devise/devise_generator.rb @@ -24,7 +24,10 @@ def install_devise require 'devise' - if File.exist?(File.join(destination_root, "config", "initializers", "devise.rb")) + initializer_file = + File.join(destination_root, "config", "initializers", "devise.rb") + + if File.exist?(initializer_file) log :generate, "No need to install devise, already done." else log :generate, "devise:install" diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 24bace099ad..0d8b1a9b5b4 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -173,7 +173,7 @@ class Tagging < ActiveRecord::Base # https://github.com/plataformatec/devise/issues/2554 gsub_file 'config/initializers/devise.rb', /# config.secret_key =/, 'config.secret_key =' -rake 'db:drop db:create db:migrate', env: ENV['RAILS_ENV'] || 'development' +rake "db:drop db:create db:migrate", env: ENV['RAILS_ENV'] || 'development' if ENV['INSTALL_PARALLEL'] inject_into_file 'config/database.yml', "<%= ENV['TEST_ENV_NUMBER'] %>", after: 'test.sqlite3' diff --git a/spec/unit/generators/install_spec.rb b/spec/unit/generators/install_spec.rb index dc0d82b83c4..e1cdb69dc31 100644 --- a/spec/unit/generators/install_spec.rb +++ b/spec/unit/generators/install_spec.rb @@ -5,19 +5,26 @@ it "active_admin.scss" do path = Rails.root + "app/assets/stylesheets/active_admin.scss" - expect(File.exist? path).to eq true + + expect(File.exist?(path)).to eq true end it "active_admin.js.coffee" do - expect(File.exist?(Rails.root + "app/assets/javascripts/active_admin.js.coffee")).to eq true + path = Rails.root + "app/assets/javascripts/active_admin.js.coffee" + + expect(File.exist?(path)).to eq true end it "the dashboard" do - expect(File.exist?(Rails.root + "app/admin/dashboard.rb")).to eq true + path = Rails.root + "app/admin/dashboard.rb" + + expect(File.exist?(path)).to eq true end it "the initializer" do - expect(File.exist?(Rails.root + "config/initializers/active_admin.rb")).to eq true + path = Rails.root + "config/initializers/active_admin.rb" + + expect(File.exist?(path)).to eq true end end From 53fd26c45e6f9320ef36d5125ae74d0a5ffdbe0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 12 Sep 2016 02:19:00 -0300 Subject: [PATCH 0229/3836] Fix nested loading bundler issue There's seems to be an issue with recent bundler/rubygems combinations when loading bundler from bundler. Prevent the issue by not doing that. --- script/local | 4 ++-- spec/spec_helper.rb | 2 -- tasks/test.rake | 5 ++++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/script/local b/script/local index 4d4e07c38bf..2e1cf45f1ab 100755 --- a/script/local +++ b/script/local @@ -38,7 +38,7 @@ unless File.exist? path --skip-turbolinks --skip-test-unit ] - system "RAILS='#{rails_version}' bundle exec rails new #{Shellwords.escape path} #{args.join ' '}" + system "RAILS='#{rails_version}' rails new #{Shellwords.escape path} #{args.join ' '}" end # Link this rails app @@ -50,4 +50,4 @@ RAILS_COMMANDS = %w{generate console server dbconsole g c s runner} args = RAILS_COMMANDS.include?(ARGV[0]) ? ["rails", ARGV].flatten : ARGV # Run the command -exec "cd test-rails-app && GEMFILE=../Gemfile bundle exec #{args.join(" ")}" +exec "cd test-rails-app && GEMFILE=../Gemfile #{args.join(" ")}" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4cfd02e6286..a212d37f967 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,8 +2,6 @@ $LOAD_PATH << File.expand_path('../support', __FILE__) ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__) -require "bundler" -Bundler.setup require 'detect_rails_version' ENV['RAILS'] = detect_rails_version diff --git a/tasks/test.rake b/tasks/test.rake index d65ff4a716e..6cebbe31cb2 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -13,7 +13,7 @@ task :setup, :parallel do |t, opts| --skip-turbolinks --skip-test-unit ] - system "#{'INSTALL_PARALLEL=yes' if opts[:parallel]} bundle exec rails new #{dir} #{args.join ' '}" + system "#{'INSTALL_PARALLEL=yes' if opts[:parallel]} rails new #{dir} #{args.join ' '}" Rake::Task['parallel:after_setup_hook'].invoke if opts[:parallel] end end @@ -72,16 +72,19 @@ require 'cucumber/rake/task' Cucumber::Rake::Task.new(:cucumber) do |t| t.profile = 'default' + t.bundler = false end namespace :cucumber do Cucumber::Rake::Task.new(:wip, "Run the cucumber scenarios with the @wip tag") do |t| t.profile = 'wip' + t.bundler = false end Cucumber::Rake::Task.new(:class_reloading, "Run the cucumber scenarios that test reloading") do |t| t.profile = 'class-reloading' + t.bundler = false end end From 69b53eb5a7dd46b2fe75fdf6bcee6e86bd42a77c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 11:26:38 -0200 Subject: [PATCH 0230/3836] Submit coverage only in CI This fixes the annoying ``` { "error": { "reason": "Please provide the repository token to upload reports via `-t :repository-token`", "context": null }, "meta": {"status": 400} } ``` --- spec/spec_helper.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a212d37f967..c9467707126 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,5 +14,7 @@ add_filter 'bundle/' # for Travis end -require 'codecov' -SimpleCov.formatter = SimpleCov::Formatter::Codecov \ No newline at end of file +if ENV['CI'] == 'true' + require 'codecov' + SimpleCov.formatter = SimpleCov::Formatter::Codecov +end From 88b17d57833fef4c9fc5f9de720283e30510d98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 11:44:20 -0200 Subject: [PATCH 0231/3836] Lock thor version This prevents annoying messages during test setup like: ``` Expected string default value for '--helper'; got true (boolean) Expected string default value for '--assets'; got true (boolean) Expected string default value for '--decorator'; got true (boolean) Expected string default value for '--decorator'; got true (boolean) ``` --- Gemfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index f81cefc44f7..a574bc23a9e 100644 --- a/Gemfile +++ b/Gemfile @@ -34,6 +34,9 @@ gem 'devise', rails_major == '5' ? '> 4.x' : '~> 3.5' gem 'draper', rails_major == '5' ? '> 3.x' : '~> 2.1' gem 'pundit' +# Until https://github.com/erikhuda/thor/issues/538 fixed +gem 'thor', '<= 0.19.1' + # Utility gems used in both development & test environments gem 'rake' gem 'parallel_tests', '< 2.10' #2.10 requires ruby '>= 2.0.0' From f08c9a26cea84e6130bdf39c5c501ef3356fecda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 12:58:06 -0300 Subject: [PATCH 0232/3836] Don't ship test files with the gem --- activeadmin.gemspec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index 8f172f39549..3cb1af2256c 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -10,7 +10,10 @@ Gem::Specification.new do |s| s.description = 'The administration framework for Ruby on Rails.' s.summary = 'The administration framework for Ruby on Rails.' - s.files = `git ls-files`.split("\n").sort + s.files = `git ls-files -z`.split("\x0").reject do |f| + f.match(%r{^(spec|features)/}) + end + s.test_files = `git ls-files -- {spec,features}/*`.split("\n") s.required_ruby_version = '>= 1.9.3' From acf72416c9703991514047517593f2f4531bf22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 20:50:29 -0200 Subject: [PATCH 0233/3836] Don't gitignore bin `bin` is the default "bindir" folder in the gemspec. Executables provided by a gem should live in this folder. In this case, the gem provides no executables, but in my case (don't know why) there was a `bin/console` script in this folder. I figure if we gitignore this folder, there's a chance that we might unintentionally ship scripts in `bin/` with the gem. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index beb2a8e0d7f..acd70ed687e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,6 @@ doc pkg ## Project (specific) -bin/ .bundle spec/rails *.sqlite3-journal From 82d5d2b7c2358a2d384aec090a97ec6d34bf1393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 13:50:39 -0200 Subject: [PATCH 0234/3836] Use Rails 5 versioned migrations --- .../templates/migrations/create_active_admin_comments.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb index 9efd14781c2..75574bf6470 100644 --- a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb +++ b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb @@ -1,4 +1,7 @@ -class CreateActiveAdminComments < ActiveRecord::Migration +parent_class = ActiveRecord::Migration +parent_class = parent_class[5.0] if Rails::VERSION::MAJOR >= 5 + +class CreateActiveAdminComments < parent_class def self.up create_table :active_admin_comments do |t| t.string :namespace From 728001facfd1bcf9344d9a4e665f82dda47d52d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 13:51:35 -0200 Subject: [PATCH 0235/3836] Don't try to generate dup indexes in Rails 5 The `references` keyword automatically generates an index for the involved columns in Rails 5. --- .../templates/migrations/create_active_admin_comments.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb index 75574bf6470..1fb5fe000ea 100644 --- a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb +++ b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb @@ -12,7 +12,11 @@ def self.up t.timestamps end add_index :active_admin_comments, [:namespace] - add_index :active_admin_comments, [:author_type, :author_id] + + unless Rails::VERSION::MAJOR >= 5 + add_index :active_admin_comments, [:author_type, :author_id] + end + add_index :active_admin_comments, [:resource_type, :resource_id] end From 94ab6918f1e14e5c38596f192dc019179d8601c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 12:17:42 -0300 Subject: [PATCH 0236/3836] Fix warning in Rails 4: adopt Rails 5 behaviour ``` DEPRECATION WARNING: `#timestamps` was called without specifying an option for `null`. In Rails 5, this behavior will change to `null: false`. You should manually specify `null: true` to prevent the behavior of your existing migrations from changing. ``` --- .../templates/migrations/create_active_admin_comments.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb index 1fb5fe000ea..104d6329234 100644 --- a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb +++ b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb @@ -9,7 +9,11 @@ def self.up t.string :resource_id, null: false t.string :resource_type, null: false t.references :author, polymorphic: true - t.timestamps + if Rails::VERSION::MAJOR >= 5 + t.timestamps + else + t.timestamps null: false + end end add_index :active_admin_comments, [:namespace] From 6274bf5a5f48fd2074ddc9626aaa8a4f3df023fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 19 Jan 2017 18:23:11 -0200 Subject: [PATCH 0237/3836] Template comments migration --- .../active_admin/install/install_generator.rb | 2 +- ...rb => create_active_admin_comments.rb.erb} | 20 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) rename lib/generators/active_admin/install/templates/migrations/{create_active_admin_comments.rb => create_active_admin_comments.rb.erb} (62%) diff --git a/lib/generators/active_admin/install/install_generator.rb b/lib/generators/active_admin/install/install_generator.rb index 6b7844ddb88..94f1d79c23e 100644 --- a/lib/generators/active_admin/install/install_generator.rb +++ b/lib/generators/active_admin/install/install_generator.rb @@ -38,7 +38,7 @@ def create_assets end def create_migrations - migration_template 'migrations/create_active_admin_comments.rb', 'db/migrate/create_active_admin_comments.rb' + migration_template 'migrations/create_active_admin_comments.rb.erb', 'db/migrate/create_active_admin_comments.rb' end end end diff --git a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb.erb similarity index 62% rename from lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb rename to lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb.erb index 104d6329234..d06c1a732c6 100644 --- a/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb +++ b/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb.erb @@ -1,7 +1,9 @@ +<% parent_class = ActiveRecord::Migration parent_class = parent_class[5.0] if Rails::VERSION::MAJOR >= 5 +%> -class CreateActiveAdminComments < parent_class +class CreateActiveAdminComments < <%= parent_class.to_s %> def self.up create_table :active_admin_comments do |t| t.string :namespace @@ -9,17 +11,17 @@ def self.up t.string :resource_id, null: false t.string :resource_type, null: false t.references :author, polymorphic: true - if Rails::VERSION::MAJOR >= 5 - t.timestamps - else - t.timestamps null: false - end + <%- if Rails::VERSION::MAJOR >= 5 -%> + t.timestamps + <%- else -%> + t.timestamps null: false + <%- end -%> end add_index :active_admin_comments, [:namespace] + <%- unless Rails::VERSION::MAJOR >= 5 -%> - unless Rails::VERSION::MAJOR >= 5 - add_index :active_admin_comments, [:author_type, :author_id] - end + add_index :active_admin_comments, [:author_type, :author_id] + <%- end -%> add_index :active_admin_comments, [:resource_type, :resource_id] end From 34db35dd18fc1fdedc29e66cdd018d3ccd0054c1 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 25 Jan 2017 23:39:49 +0200 Subject: [PATCH 0238/3836] fixes #4757, allow to turn on/off current filters sidebar --- features/index/filters.feature | 20 +++++++++++++++++++ .../filters/resource_extension.rb | 6 ++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/features/index/filters.feature b/features/index/filters.feature index 0aac6b229fc..7f309ccf7f6 100644 --- a/features/index/filters.feature +++ b/features/index/filters.feature @@ -158,4 +158,24 @@ Feature: Index Filtering And I should see "Non-Fiction" within ".index_table" And the "Jane Doe" checkbox should be checked + Scenario: Enabling filters status sidebar + Given an index configuration of: + """ + ActiveAdmin.application.current_filters = false + ActiveAdmin.register Post do + config.current_filters = true + end + """ + And I press "Filter" + Then I should see a sidebar titled "Search Status:" + Scenario: Disabling filters status sidebar + Given an index configuration of: + """ + ActiveAdmin.application.current_filters = true + ActiveAdmin.register Post do + config.current_filters = false + end + """ + And I press "Filter" + Then I should not see a sidebar titled "Search Status:" \ No newline at end of file diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index d6cbe45a8a5..29fc6882354 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -157,13 +157,11 @@ def filters_sidebar_section end def add_search_status_sidebar_section - if current_filters_enabled? - self.sidebar_sections << search_status_section - end + self.sidebar_sections << search_status_section end def search_status_section - ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.headline"), only: :index, if: -> { params[:q] || params[:scope] } do + ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.headline"), only: :index, if: -> {active_admin_config.current_filters_enabled? && (params[:q] || params[:scope]) } do active = ActiveAdmin::Filters::Active.new(resource_class, params) span do From 8a904e72972207424e4844fbe562787307a38e94 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 26 Jan 2017 00:16:31 +0200 Subject: [PATCH 0239/3836] siplify sidebar cucumber step implementation --- features/step_definitions/sidebar_steps.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/features/step_definitions/sidebar_steps.rb b/features/step_definitions/sidebar_steps.rb index 2f345a80cae..477b2405daa 100644 --- a/features/step_definitions/sidebar_steps.rb +++ b/features/step_definitions/sidebar_steps.rb @@ -3,9 +3,7 @@ end Then /^I should not see a sidebar titled "([^"]*)"$/ do |title| - title = title.tr(' ', '').underscore - sidebars = page.all :css, "##{title}_sidebar_section" - expect(sidebars.count).to eq 0 + expect(page).not_to have_css '.sidebar_section h3', text: title end Then(/^I should see a sidebar titled "(.*?)" above sidebar titled "(.*?)"$/) do |top_title, bottom_title| From e3773f44bed93f4e2e035e40759bd8126bb82417 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 26 Jan 2017 08:18:55 +0100 Subject: [PATCH 0240/3836] configure codecov.io This is the default config but with PR comments disabled. --- codecov.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000000..5366f75f9f7 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,23 @@ +codecov: + notify: + require_ci_to_pass: true +comment: off +coverage: + precision: 2 + range: + - 70.0 + - 100.0 + round: down + status: + changes: false + patch: true + project: true +parsers: + gcov: + branch_detection: + conditional: true + loop: true + macro: false + method: false + javascript: + enable_partials: false From d4861318ea6cdbd07a0f7584998ec614b62fd207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 14:44:39 -0300 Subject: [PATCH 0241/3836] Fix gem name Flamegraph's fallback is `fast_stack`, not `fast_track`. Who knows what we were previously installing... --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index a574bc23a9e..90f541abe0d 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,7 @@ group :development do # Flamegraph dependency gem 'stackprof', platforms: [:mri_21, :mri_22, :mri_23], require: false - gem 'fast_track', platforms: [:mri_19, :mri_20], require: false + gem 'fast_stack', platforms: [:mri_19, :mri_20], require: false # Documentation gem 'yard' # Documentation generator From 796fe5b09e8f4154bbcafcc00649fe7eecaacbac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 12:03:57 -0300 Subject: [PATCH 0242/3836] Remove unnecessary version constraint The current setup is complicated enough. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 90f541abe0d..b8ef1652b80 100644 --- a/Gemfile +++ b/Gemfile @@ -80,7 +80,7 @@ group :test do gem 'jslint_on_rails' gem 'launchy' gem 'rails-i18n' # Provides default i18n for many languages - gem 'rspec-rails', '>= 3.5.0.beta1' + gem 'rspec-rails' gem 'i18n-spec' gem 'shoulda-matchers', '<= 2.8.0' gem 'sqlite3', platforms: :mri From 86ae8d3b9d07ade4c64347725b78de0e9dbd0136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 12 Sep 2016 12:20:02 -0300 Subject: [PATCH 0243/3836] Remove listen dependency My guess is that nobody is using this, so the best way to prevent future platform dependency issues is to get rid of it. If some developer is using it, it could be added locally. --- Gemfile | 2 -- Guardfile | 8 -------- script/local | 1 + tasks/test.rake | 1 + 4 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 Guardfile diff --git a/Gemfile b/Gemfile index b8ef1652b80..61e8ba821c5 100644 --- a/Gemfile +++ b/Gemfile @@ -74,8 +74,6 @@ group :test do gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' gem 'database_cleaner' - gem 'guard-rspec', require: false - gem 'listen', '~> 2.7', platforms: [:ruby_19, :jruby] gem 'jasmine' gem 'jslint_on_rails' gem 'launchy' diff --git a/Guardfile b/Guardfile deleted file mode 100644 index e2270e628f5..00000000000 --- a/Guardfile +++ /dev/null @@ -1,8 +0,0 @@ -# More info at https://github.com/guard/guard#readme - -guard 'rspec', all_on_start: false, version: 2 do - watch(%r{^spec/.+_spec\.rb$}) - watch(%r{^lib/active_admin/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { "spec/" } - watch('spec/rails_helper.rb') { "spec/" } -end diff --git a/script/local b/script/local index 2e1cf45f1ab..6bab77133de 100755 --- a/script/local +++ b/script/local @@ -35,6 +35,7 @@ unless File.exist? path --skip-gemfile --skip-bundle --skip-git + --skip-listen --skip-turbolinks --skip-test-unit ] diff --git a/tasks/test.rake b/tasks/test.rake index 6cebbe31cb2..d2384a5ca5a 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -10,6 +10,7 @@ task :setup, :parallel do |t, opts| --skip-gemfile --skip-bundle --skip-git + --skip-listen --skip-turbolinks --skip-test-unit ] From 28fcb3a7a4b092a07a32ea68d1bc0589fdc69671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 14:49:27 -0200 Subject: [PATCH 0244/3836] Remove now unnecessary constraints The need for this was removed when introducing codecov.io, but readded later unintentionally. --- Gemfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index 61e8ba821c5..13772b736c2 100644 --- a/Gemfile +++ b/Gemfile @@ -68,9 +68,7 @@ end group :test do gem 'capybara' gem 'simplecov', require: false # Test coverage generator. Go to /coverage/ after running tests - gem 'json', '~> 1.8', require: false # Required by simplecov, > 2 removes support for Ruby 1.9 gem 'codecov', require: false # Test coverage website. Go to https://codecov.io - gem 'tins', '~> 1.6.0', require: false # Required by coveralls, > 1.6.0 removes support for Ruby 1.9 gem 'cucumber-rails', require: false gem 'cucumber', '1.3.20' gem 'database_cleaner' From 6dbf1bd29f13f3a3567dfb89ee2ed61c9d20af50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 21 Jan 2017 18:39:57 -0200 Subject: [PATCH 0245/3836] Bump jruby version to 9.1.7.0 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e684e11ac20..ac2f15b0a48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ script: - bundle exec rake test rvm: - - jruby-9.1.6.0 + - jruby-9.1.7.0 - 1.9.3 - 2.2.6 - 2.3.3 @@ -45,7 +45,7 @@ matrix: env: RAILS=5.0.1 allow_failures: - - rvm: jruby-9.1.6.0 + - rvm: jruby-9.1.7.0 env: RAILS=5.0.1 notifications: From 98e1f710b782d399ef7db25ef3cf7adbf98146c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 21 Jan 2017 18:40:31 -0200 Subject: [PATCH 0246/3836] Test against 2.4.0 Only one spec to be fixed, and it's actually a bug fix brought to you by the awesome ruby 2.4.0 unicode case mappings! ;) The new Travis matrix is as follows: * Ruby 2.4.0 + Rails {3.2,4.0,4.1} combination segfaults. Since those Rails versions are already EOLed, I think it's pointless to try to bother with them, since the segfaults probably comes from inside Rails and they will no longer be patched. * Ruby 2.4.0 + Rails 4.2 fails, but Ruby 2.4 support will be added in the next release. So I add it to `allowed_failures` but we should be able to move it back to the regular matrix once 4.2.8 is released. --- .travis.yml | 13 +++++++++++++ spec/unit/page_spec.rb | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ac2f15b0a48..1d9f23c1009 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ rvm: - 1.9.3 - 2.2.6 - 2.3.3 + - 2.4.0 env: matrix: @@ -44,10 +45,22 @@ matrix: - rvm: 1.9.3 env: RAILS=5.0.1 + - rvm: 2.4.0 + env: RAILS=3.2.22 + + - rvm: 2.4.0 + env: RAILS=4.0.13 + + - rvm: 2.4.0 + env: RAILS=4.1.16 + allow_failures: - rvm: jruby-9.1.7.0 env: RAILS=5.0.1 + - rvm: 2.4.0 + env: RAILS=4.2.7.1 + notifications: irc: channels: diff --git a/spec/unit/page_spec.rb b/spec/unit/page_spec.rb index 3c487b2753c..2f37f799e71 100644 --- a/spec/unit/page_spec.rb +++ b/spec/unit/page_spec.rb @@ -34,7 +34,11 @@ def config(options = {}) end it "returns the singular, lowercase name" do - expect(config.resource_name.singular).to eq "chocolate i lØve you!" + if RUBY_VERSION >= '2.4.0' + expect(config.resource_name.singular).to eq "chocolate i løve you!" + else + expect(config.resource_name.singular).to eq "chocolate i lØve you!" + end end end From b212d8cb60683f3ad29dc0fa67b20891ac9b05cc Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Tue, 24 Jan 2017 09:50:59 +0200 Subject: [PATCH 0247/3836] Remove DataAccess#clean_search_params ransack cleaning params by itslef, so no need to do it twice --- lib/active_admin/resource_controller/data_access.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index fc68fd09c7a..48912346246 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -222,16 +222,10 @@ def apply_sorting(chain) # Applies any Ransack search methods to the currently scoped collection. # Both `search` and `ransack` are provided, but we use `ransack` to prevent conflicts. def apply_filtering(chain) - @search = chain.ransack clean_search_params + @search = chain.ransack(params[:q] || {}) @search.result end - def clean_search_params - q = params[:q] || {} - q = q.to_unsafe_h if q.respond_to? :to_unsafe_h - q.delete_if{ |key, value| value.blank? } - end - def apply_scoping(chain) @collection_before_scope = chain From 1ac631d329a965a262211b44b837193030acefbb Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 25 Jan 2017 12:10:55 +0200 Subject: [PATCH 0248/3836] added test to check blank params are not included while filtering --- .../unit/resource_controller/data_access_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/unit/resource_controller/data_access_spec.rb b/spec/unit/resource_controller/data_access_spec.rb index e0de719f1ee..5d268880465 100644 --- a/spec/unit/resource_controller/data_access_spec.rb +++ b/spec/unit/resource_controller/data_access_spec.rb @@ -20,6 +20,22 @@ expect(chain).to receive(:ransack).with(params[:q]).once.and_return(Post.ransack) controller.send :apply_filtering, chain end + + context "params includes empty values" do + let(:params) do + { q: {id_eq: 1, position_eq: ""} } + end + it "should return relation without empty filters" do + expect(Post).to receive(:ransack).with(params[:q]).once.and_wrap_original do |original, *args| + chain = original.call(*args) + expect(chain.conditions.size).to eq(1) + chain + end + controller.send :apply_filtering, Post + end + end + + end describe "sorting" do From ef4e80ea2f0cb528ea146becd104f7b5b029910d Mon Sep 17 00:00:00 2001 From: Roman Shatsov Date: Wed, 4 Dec 2013 18:05:23 +0300 Subject: [PATCH 0249/3836] Fix auto_link --- features/index/batch_actions.feature | 22 +++++++++++++++++ .../batch_actions/resource_extension.rb | 9 ++++--- .../batch_actions/views/batch_action_form.rb | 2 +- lib/active_admin/resource/menu.rb | 2 +- lib/active_admin/resource/routes.rb | 24 +++++++++---------- .../view_helpers/auto_link_helper.rb | 4 ++-- spec/unit/auto_link_spec.rb | 11 ++++----- spec/unit/view_helpers/display_helper_spec.rb | 4 ++++ 8 files changed, 53 insertions(+), 25 deletions(-) diff --git a/features/index/batch_actions.feature b/features/index/batch_actions.feature index bbdc6d77e13..c5271d93ecc 100644 --- a/features/index/batch_actions.feature +++ b/features/index/batch_actions.feature @@ -21,6 +21,28 @@ Feature: Batch Actions Then I should see a flash with "Successfully destroyed 2 posts" And I should see 8 posts in the table + Scenario: Use default (destroy) batch action when default_url_options present + Given 3 posts exist + And an index configuration of: + """ + ActiveAdmin.register Post do + controller do + protected + + def default_url_options + { locale: I18n.locale } + end + end + end + """ + When I check the 1st record + And I follow "Batch Actions" + Then I should see the batch action :destroy "Delete Selected" + + Given I submit the batch action form with "destroy" + Then I should see a flash with "Successfully destroyed 1 post" + And I should see 2 posts in the table + Scenario: Use default (destroy) batch action on a decorated resource Given 5 posts exist And an index configuration of: diff --git a/lib/active_admin/batch_actions/resource_extension.rb b/lib/active_admin/batch_actions/resource_extension.rb index 31f606e09d4..a1b7278111f 100644 --- a/lib/active_admin/batch_actions/resource_extension.rb +++ b/lib/active_admin/batch_actions/resource_extension.rb @@ -52,12 +52,15 @@ def clear_batch_actions! end # Path to the batch action itself - def batch_action_path(params = {}) - path = [route_collection_path(params), "batch_action"].join("/") + def batch_action_path(params = {}, url_options = {}) + uri = URI(route_collection_path(params, url_options)) + uri.path += "/batch_action" + query = params.slice(:q, :scope) query = query.permit! if query.respond_to? :permit! query = query.to_h if Rails::VERSION::MAJOR >= 5 - [path, query.to_param].reject(&:blank?).join("?") + uri.query = [uri.query, query.to_param].compact.join('&') if query.present? + uri.to_s end private diff --git a/lib/active_admin/batch_actions/views/batch_action_form.rb b/lib/active_admin/batch_actions/views/batch_action_form.rb index bf545f2ecc3..f5a95530461 100644 --- a/lib/active_admin/batch_actions/views/batch_action_form.rb +++ b/lib/active_admin/batch_actions/views/batch_action_form.rb @@ -15,7 +15,7 @@ def build(options = {}, &block) # Open a form with two hidden input fields: # batch_action => name of the specific action called # batch_action_inputs => a JSON string of any requested confirmation values - text_node form_tag active_admin_config.batch_action_path(params), id: options[:id] + text_node form_tag active_admin_config.batch_action_path(params, url_options), id: options[:id] input name: :batch_action, id: :batch_action, type: :hidden input name: :batch_action_inputs, id: :batch_action_inputs, type: :hidden diff --git a/lib/active_admin/resource/menu.rb b/lib/active_admin/resource/menu.rb index 9c8d22e097a..a9d1bfac802 100644 --- a/lib/active_admin/resource/menu.rb +++ b/lib/active_admin/resource/menu.rb @@ -26,7 +26,7 @@ def default_menu_options { id: resource_name.plural, label: proc{ resource.plural_resource_label }, - url: proc{ resource.route_collection_path(params) }, + url: proc{ resource.route_collection_path(params, url_options) }, if: proc{ authorized?(Auth::READ, menu_resource_class) } } end diff --git a/lib/active_admin/resource/routes.rb b/lib/active_admin/resource/routes.rb index 9061f98de66..b5c70e6f650 100644 --- a/lib/active_admin/resource/routes.rb +++ b/lib/active_admin/resource/routes.rb @@ -4,19 +4,19 @@ module Routes # @param params [Hash] of params: { study_id: 3 } # @return [String] the path to this resource collection page # @example "/admin/posts" - def route_collection_path(params = {}) - RouteBuilder.new(self).collection_path(params) + def route_collection_path(params = {}, additional_params = {}) + RouteBuilder.new(self).collection_path(params, additional_params) end # @param resource [ActiveRecord::Base] the instance we want the path of # @return [String] the path to this resource collection page # @example "/admin/posts/1" - def route_instance_path(resource) - RouteBuilder.new(self).instance_path(resource) + def route_instance_path(resource, additional_params = {}) + RouteBuilder.new(self).instance_path(resource, additional_params) end - def route_edit_instance_path(resource) - RouteBuilder.new(self).edit_instance_path(resource) + def route_edit_instance_path(resource, additional_params = {}) + RouteBuilder.new(self).edit_instance_path(resource, additional_params) end # Returns the routes prefix for this config @@ -37,32 +37,32 @@ def initialize(resource) @resource = resource end - def collection_path(params) + def collection_path(params, additional_params = {}) route_name = route_name( resource.resources_configuration[:self][:route_collection_name], suffix: (resource.route_uncountable? ? "index_path" : "path") ) - routes.public_send route_name, *route_collection_params(params) + routes.public_send route_name, *route_collection_params(params), additional_params end # @return [String] the path to this resource collection page # @param instance [ActiveRecord::Base] the instance we want the path of # @example "/admin/posts/1" - def instance_path(instance) + def instance_path(instance, additional_params = {}) route_name = route_name(resource.resources_configuration[:self][:route_instance_name]) - routes.public_send route_name, *route_instance_params(instance) + routes.public_send route_name, *route_instance_params(instance), additional_params end # @return [String] the path to the edit page of this resource # @param instance [ActiveRecord::Base] the instance we want the path of # @example "/admin/posts/1/edit" - def edit_instance_path(instance) + def edit_instance_path(instance, additional_params = {}) path = resource.resources_configuration[:self][:route_instance_name] route_name = route_name(path, action: :edit) - routes.public_send route_name, *route_instance_params(instance) + routes.public_send route_name, *route_instance_params(instance), additional_params end private diff --git a/lib/active_admin/view_helpers/auto_link_helper.rb b/lib/active_admin/view_helpers/auto_link_helper.rb index 69935a6f6fd..3e1d1506f69 100644 --- a/lib/active_admin/view_helpers/auto_link_helper.rb +++ b/lib/active_admin/view_helpers/auto_link_helper.rb @@ -26,10 +26,10 @@ def auto_url_for(resource) if config.controller.action_methods.include?("show") && authorized?(ActiveAdmin::Auth::READ, resource) - url_for config.route_instance_path resource + url_for config.route_instance_path resource, url_options elsif config.controller.action_methods.include?("edit") && authorized?(ActiveAdmin::Auth::UPDATE, resource) - url_for config.route_edit_instance_path resource + url_for config.route_edit_instance_path resource, url_options end end diff --git a/spec/unit/auto_link_spec.rb b/spec/unit/auto_link_spec.rb index a6eb3b8181c..85ba0fb41d2 100644 --- a/spec/unit/auto_link_spec.rb +++ b/spec/unit/auto_link_spec.rb @@ -10,10 +10,6 @@ let(:active_admin_namespace){ ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) } let(:post){ Post.create! title: "Hello World" } - def admin_post_path(post) - "/admin/posts/#{post.id}" - end - def authorized?(*) true end @@ -29,8 +25,10 @@ def authorized?(*) active_admin_namespace.register Post end it "should return a link with the display name of the object" do + url_path = "/admin/posts/#{post.id}?locale=en" + expect(self).to receive(:url_options).and_return(locale: 'en') expect(self).to receive(:url_for) { |url| url } - expect(self).to receive(:link_to).with "Hello World", admin_post_path(post) + expect(self).to receive(:link_to).with "Hello World", url_path auto_link(post) end @@ -47,7 +45,8 @@ def authorized?(*) end it "should fallback to edit" do - url_path = "/admin/posts/#{post.id}/edit" + url_path = "/admin/posts/#{post.id}/edit?locale=en" + expect(self).to receive(:url_options).and_return(locale: 'en') expect(self).to receive(:url_for) { |url| url } expect(self).to receive(:link_to).with "Hello World", url_path auto_link(post) diff --git a/spec/unit/view_helpers/display_helper_spec.rb b/spec/unit/view_helpers/display_helper_spec.rb index bad44c99711..d569233814e 100644 --- a/spec/unit/view_helpers/display_helper_spec.rb +++ b/spec/unit/view_helpers/display_helper_spec.rb @@ -16,6 +16,10 @@ def authorized?(*) true end + def url_options + { locale: nil } + end + describe '#display_name' do ActiveAdmin::Application.new.display_name_methods.map(&:to_s).each do |m| it "should return #{m} when defined" do From 09f2667b35d5ff320a8b8c51cdba198ad13f66b3 Mon Sep 17 00:00:00 2001 From: Roman Shatsov Date: Fri, 27 Jan 2017 13:47:18 +0300 Subject: [PATCH 0250/3836] Use default batch_action_path helper --- .../batch_actions/resource_extension.rb | 12 ----------- .../batch_actions/views/batch_action_form.rb | 2 +- lib/active_admin/resource/routes.rb | 14 +++++++++++++ spec/unit/batch_actions/resource_spec.rb | 13 ------------ spec/unit/resource/routes_spec.rb | 21 +++++++++++++++++++ 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/lib/active_admin/batch_actions/resource_extension.rb b/lib/active_admin/batch_actions/resource_extension.rb index a1b7278111f..f50c426ed91 100644 --- a/lib/active_admin/batch_actions/resource_extension.rb +++ b/lib/active_admin/batch_actions/resource_extension.rb @@ -51,18 +51,6 @@ def clear_batch_actions! @batch_actions = {} end - # Path to the batch action itself - def batch_action_path(params = {}, url_options = {}) - uri = URI(route_collection_path(params, url_options)) - uri.path += "/batch_action" - - query = params.slice(:q, :scope) - query = query.permit! if query.respond_to? :permit! - query = query.to_h if Rails::VERSION::MAJOR >= 5 - uri.query = [uri.query, query.to_param].compact.join('&') if query.present? - uri.to_s - end - private # @return [ActiveAdmin::BatchAction] The default "delete" action diff --git a/lib/active_admin/batch_actions/views/batch_action_form.rb b/lib/active_admin/batch_actions/views/batch_action_form.rb index f5a95530461..a7a18c8ace6 100644 --- a/lib/active_admin/batch_actions/views/batch_action_form.rb +++ b/lib/active_admin/batch_actions/views/batch_action_form.rb @@ -15,7 +15,7 @@ def build(options = {}, &block) # Open a form with two hidden input fields: # batch_action => name of the specific action called # batch_action_inputs => a JSON string of any requested confirmation values - text_node form_tag active_admin_config.batch_action_path(params, url_options), id: options[:id] + text_node form_tag active_admin_config.route_batch_action_path(params, url_options), id: options[:id] input name: :batch_action, id: :batch_action, type: :hidden input name: :batch_action_inputs, id: :batch_action_inputs, type: :hidden diff --git a/lib/active_admin/resource/routes.rb b/lib/active_admin/resource/routes.rb index b5c70e6f650..7831bb00b45 100644 --- a/lib/active_admin/resource/routes.rb +++ b/lib/active_admin/resource/routes.rb @@ -8,6 +8,10 @@ def route_collection_path(params = {}, additional_params = {}) RouteBuilder.new(self).collection_path(params, additional_params) end + def route_batch_action_path(params = {}, additional_params = {}) + RouteBuilder.new(self).batch_action_path(params, additional_params) + end + # @param resource [ActiveRecord::Base] the instance we want the path of # @return [String] the path to this resource collection page # @example "/admin/posts/1" @@ -46,6 +50,16 @@ def collection_path(params, additional_params = {}) routes.public_send route_name, *route_collection_params(params), additional_params end + def batch_action_path(params, additional_params = {}) + path = resource.resources_configuration[:self][:route_collection_name] + route_name = route_name(path, action: :batch_action) + + query = params.slice(:q, :scope) + query = query.permit! if query.respond_to? :permit! + query = query.to_h if Rails::VERSION::MAJOR >= 5 + routes.public_send route_name, *route_collection_params(params), additional_params.merge(query) + end + # @return [String] the path to this resource collection page # @param instance [ActiveRecord::Base] the instance we want the path of # @example "/admin/posts/1" diff --git a/spec/unit/batch_actions/resource_spec.rb b/spec/unit/batch_actions/resource_spec.rb index 8120c1052c6..5fd3152b158 100644 --- a/spec/unit/batch_actions/resource_spec.rb +++ b/spec/unit/batch_actions/resource_spec.rb @@ -52,19 +52,6 @@ end - describe "#batch_action_path" do - - it "returns the path as a symbol" do - expect(resource.batch_action_path).to eq "/admin/posts/batch_action" - end - - it "includes :scope and :q params" do - params = { q: { name_equals: "Any" }, scope: :all } - batch_action_path = "/admin/posts/batch_action?q%5Bname_equals%5D=Any&scope=all" - expect(resource.batch_action_path(params)).to eq(batch_action_path) - end - end - describe "#display_if_block" do it "should return true by default" do diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 0ebfb6c7ae5..7b95d708326 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -101,6 +101,27 @@ class ::News; def self.has_many(*); end end expect(config.route_instance_path(tagging)).to eq "/admin/categories/1/posts/3/taggings/4" end end + + context "for batch_action handler" do + let! :config do + ActiveAdmin.register Post do + belongs_to :category + end + end + + before do + config.batch_actions= true + reload_routes! + end + + it "should include :scope and :q params" do + params = { category_id: 1, q: { name_equals: "Any" }, scope: :all } + additional_params = { locale: 'en' } + batch_action_path = "/admin/categories/1/posts/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + + expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path + end + end end end end From 3c5569f356135f4f771bbce8d8684ccd14dad389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 20:53:25 -0200 Subject: [PATCH 0251/3836] Fix `script/local`'s help --- script/local | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/local b/script/local index 6bab77133de..e5afed69d61 100755 --- a/script/local +++ b/script/local @@ -5,7 +5,7 @@ require File.expand_path('../../spec/support/detect_rails_version', __FILE__) unless ARGV[0] puts <<-EOF -Usage: ./script/#{__FILE__} COMMAND [ARGS] +Usage: #{__FILE__} COMMAND [ARGS] The command will be run in the context of the local rails app stored in test-rails-app. From 5f045e07c6b4327e804181ee977f914152db70d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 20:53:41 -0200 Subject: [PATCH 0252/3836] Make `script/local` help text more resilient Since it no longer depends on the name of the script. --- script/local | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script/local b/script/local index e5afed69d61..949ab8da2d0 100755 --- a/script/local +++ b/script/local @@ -12,9 +12,9 @@ app stored in test-rails-app. Examples: -./script/local server -./script/local c -./script/local rake db:migrate +#{__FILE__} server +#{__FILE__} c +#{__FILE__} rake db:migrate EOF exit(1) end From ca308df162c2e999bd1b1f0be1b4aec2580c499b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 26 Jan 2017 08:23:28 -0200 Subject: [PATCH 0253/3836] Fix an error when creating the sample app ``` /path/to/.test-rails-apps/test-rails-app-5.0.1/Gemfile not found ``` --- script/local | 1 - tasks/test.rake | 1 - 2 files changed, 2 deletions(-) diff --git a/script/local b/script/local index 949ab8da2d0..cb6f7ceffaf 100755 --- a/script/local +++ b/script/local @@ -32,7 +32,6 @@ system "mkdir #{dir}" unless File.exist?(dir) unless File.exist? path args = %w[ -m\ spec/support/rails_template_with_data.rb - --skip-gemfile --skip-bundle --skip-git --skip-listen diff --git a/tasks/test.rake b/tasks/test.rake index d2384a5ca5a..fde75435812 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -7,7 +7,6 @@ task :setup, :parallel do |t, opts| system 'mkdir -p spec/rails' args = %w[ -m\ spec/support/rails_template.rb - --skip-gemfile --skip-bundle --skip-git --skip-listen From 03dfc8903c80d7beeaa99d8021d4f0184b301190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 26 Jan 2017 09:31:40 -0200 Subject: [PATCH 0254/3836] Remove unnecessary space escaping --- script/local | 2 +- tasks/test.rake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/script/local b/script/local index cb6f7ceffaf..b5cb6a86d8c 100755 --- a/script/local +++ b/script/local @@ -31,7 +31,7 @@ system "mkdir #{dir}" unless File.exist?(dir) # Create the sample rails app if it doesn't already exist unless File.exist? path args = %w[ - -m\ spec/support/rails_template_with_data.rb + -m spec/support/rails_template_with_data.rb --skip-bundle --skip-git --skip-listen diff --git a/tasks/test.rake b/tasks/test.rake index fde75435812..4cf96d53d25 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -6,7 +6,7 @@ task :setup, :parallel do |t, opts| else system 'mkdir -p spec/rails' args = %w[ - -m\ spec/support/rails_template.rb + -m spec/support/rails_template.rb --skip-bundle --skip-git --skip-listen From 48fe65ba9132481664174adb9659b22661f98163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 26 Jan 2017 09:32:20 -0200 Subject: [PATCH 0255/3836] Properly setup dependencies of the sample app Through the Gemfile instead of direct LOAD_PATH manipulation. --- script/local | 2 +- spec/support/rails_template.rb | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/script/local b/script/local index b5cb6a86d8c..0e511d73183 100755 --- a/script/local +++ b/script/local @@ -50,4 +50,4 @@ RAILS_COMMANDS = %w{generate console server dbconsole g c s runner} args = RAILS_COMMANDS.include?(ARGV[0]) ? ["rails", ARGV].flatten : ARGV # Run the command -exec "cd test-rails-app && GEMFILE=../Gemfile #{args.join(" ")}" +exec "cd test-rails-app && #{args.join(" ")}" diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 0d8b1a9b5b4..7b7f6699a8a 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -135,13 +135,15 @@ class Tagging < ActiveRecord::Base RUBY -# Add our local Active Admin to the load path -inject_into_file 'config/environment.rb', <<-RUBY, after: "require File.expand_path('../application', __FILE__)" +# Add our local Active Admin to the application +gem 'activeadmin', path: '../..' +gem 'inherited_resources', git: 'https://github.com/activeadmin/inherited_resources' +gem 'devise' -$LOAD_PATH.unshift '#{File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))}' -require 'active_admin' +run 'bundle install' -RUBY +# Setup Active Admin +generate 'active_admin:install' # Force strong parameters to raise exceptions inject_into_file 'config/application.rb', <<-RUBY, after: 'class Application < Rails::Application' @@ -159,10 +161,6 @@ class Tagging < ActiveRecord::Base # Add predefined policies directory File.expand_path('../templates/policies', __FILE__), 'app/policies' -$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib') - -generate 'active_admin:install' - if ENV['RAILS_ENV'] != 'test' inject_into_file 'config/routes.rb', "\n root to: redirect('admin')", after: /.*routes.draw do/ end From 73afa3eaa2d680d0b28bd921785571013eaf167c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 26 Jan 2017 12:05:02 -0200 Subject: [PATCH 0256/3836] Make sure we reset both DBs when creating the app `rake setup` can be run in both environment, so the old way could create inconsistencies between DBs. --- spec/support/rails_template.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 7b7f6699a8a..4b64afcac16 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -171,7 +171,8 @@ class Tagging < ActiveRecord::Base # https://github.com/plataformatec/devise/issues/2554 gsub_file 'config/initializers/devise.rb', /# config.secret_key =/, 'config.secret_key =' -rake "db:drop db:create db:migrate", env: ENV['RAILS_ENV'] || 'development' +rake "db:drop db:create db:migrate", env: 'development' +rake "db:drop db:create db:migrate", env: 'test' if ENV['INSTALL_PARALLEL'] inject_into_file 'config/database.yml', "<%= ENV['TEST_ENV_NUMBER'] %>", after: 'test.sqlite3' From ae04288c3bfe0bd63e8227ec9dee7731241202b4 Mon Sep 17 00:00:00 2001 From: Mateus Gomes Date: Fri, 2 Dec 2016 19:59:00 -0300 Subject: [PATCH 0257/3836] Fix all DOM ready binding to rely on `.ready()` method, as `on('ready')` has been removed on jQuery 3 More info: https://api.jquery.com/ready/ "There is also $(document).on( "ready", handler ), deprecated as of jQuery 1.8 and removed in jQuery 3.0..." --- .../active_admin/initializers/batch_actions.js.coffee | 6 +++++- .../active_admin/initializers/datepicker.js.coffee | 6 +++++- .../active_admin/initializers/filters.js.coffee | 6 +++++- .../javascripts/active_admin/initializers/tabs.js.coffee | 6 +++++- .../javascripts/active_admin/lib/batch_actions.js.coffee | 7 +++++-- .../javascripts/active_admin/lib/dropdown-menu.js.coffee | 6 +++++- .../javascripts/active_admin/lib/per_page.js.coffee | 8 ++++++-- 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee b/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee index fe4a04633be..349ae3a2e83 100644 --- a/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee @@ -1,7 +1,11 @@ -$(document).on 'ready page:load turbolinks:load', -> +onDOMReady = -> # In order for index scopes to overflow properly onto the next line, we have # to manually set its width based on the width of the batch action button. if (batch_actions_selector = $('.table_tools .batch_actions_selector')).length batch_actions_selector.next().css width: "calc(100% - 10px - #{batch_actions_selector.outerWidth()}px)" 'float': 'right' + +$(document). + ready(onDOMReady). + on 'page:load turbolinks:load', onDOMReady diff --git a/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee b/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee index fcbd4dc6916..f3ab580c56e 100644 --- a/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee @@ -1,4 +1,4 @@ -$(document).on 'ready page:load turbolinks:load', -> +onDOMReady = -> $(document).on 'focus', 'input.datepicker:not(.hasDatepicker)', -> input = $(@) @@ -8,3 +8,7 @@ $(document).on 'ready page:load turbolinks:load', -> defaults = dateFormat: 'yy-mm-dd' options = input.data 'datepicker-options' input.datepicker $.extend(defaults, options) + +$(document). + ready(onDOMReady). + on 'page:load turbolinks:load', onDOMReady diff --git a/app/assets/javascripts/active_admin/initializers/filters.js.coffee b/app/assets/javascripts/active_admin/initializers/filters.js.coffee index 83122fc9709..98a0d36a7e1 100644 --- a/app/assets/javascripts/active_admin/initializers/filters.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/filters.js.coffee @@ -1,4 +1,4 @@ -$(document).on 'ready page:load turbolinks:load', -> +onDOMReady = -> # Clear Filters button $('.clear_filters_btn').click (e) -> params = window.location.search.slice(1).split('&') @@ -20,3 +20,7 @@ $(document).on 'ready page:load turbolinks:load', -> # a dropdown, apply that choice to the filter input field. $('.filter_form_field.select_and_search select').change -> $(@).siblings('input').prop name: "q[#{@value}]" + +$(document). + ready(onDOMReady). + on 'page:load turbolinks:load', onDOMReady diff --git a/app/assets/javascripts/active_admin/initializers/tabs.js.coffee b/app/assets/javascripts/active_admin/initializers/tabs.js.coffee index 33a5dc5cf6e..47d2d9cc816 100644 --- a/app/assets/javascripts/active_admin/initializers/tabs.js.coffee +++ b/app/assets/javascripts/active_admin/initializers/tabs.js.coffee @@ -1,3 +1,7 @@ -$(document).on 'ready page:load turbolinks:load', -> +onDOMReady = -> # Tab navigation $('#active_admin_content .tabs').tabs() + +$(document). + ready(onDOMReady). + on 'page:load turbolinks:load', onDOMReady diff --git a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee index 1a9f787b7bf..414922e6e1e 100644 --- a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee +++ b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee @@ -1,5 +1,4 @@ -$(document).on 'ready page:load turbolinks:load', -> - +onDOMReady = -> # # Use ActiveAdmin.modal_dialog to prompt user if confirmation is required for current Batch Action # @@ -37,3 +36,7 @@ $(document).on 'ready page:load turbolinks:load', -> $(".batch_actions_selector").each -> $(@).aaDropdownMenu("enable") else $(".batch_actions_selector").each -> $(@).aaDropdownMenu("disable") + +$(document). + ready(onDOMReady). + on 'page:load turbolinks:load', onDOMReady diff --git a/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee b/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee index bdb7b7c0233..515aa24d8a0 100644 --- a/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee +++ b/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee @@ -97,5 +97,9 @@ class ActiveAdmin.DropdownMenu $.widget.bridge 'aaDropdownMenu', ActiveAdmin.DropdownMenu -$(document).on 'ready page:load turbolinks:load', -> +onDOMReady = -> $('.dropdown_menu').aaDropdownMenu() + +$(document). + ready(onDOMReady). + on 'page:load turbolinks:load', onDOMReady diff --git a/app/assets/javascripts/active_admin/lib/per_page.js.coffee b/app/assets/javascripts/active_admin/lib/per_page.js.coffee index dd3ba3ae2fb..5f178eee9cd 100644 --- a/app/assets/javascripts/active_admin/lib/per_page.js.coffee +++ b/app/assets/javascripts/active_admin/lib/per_page.js.coffee @@ -23,7 +23,7 @@ class ActiveAdmin.PerPage while m = re.exec(query) params[@_decode(m[1])] = @_decode(m[2]) params - + _decode: (value) -> #replace "+" before decodeURIComponent decodeURIComponent(value.replace(/\+/g, '%20')) @@ -38,5 +38,9 @@ class ActiveAdmin.PerPage $.widget.bridge 'perPage', ActiveAdmin.PerPage -$(document).on 'ready page:load turbolinks:load', -> +onDOMReady = -> $('.pagination_per_page select').perPage() + +$(document). + ready(onDOMReady). + on 'page:load turbolinks:load', onDOMReady From 3030cb1e0dac1765a41e6011ca329fd362953ab1 Mon Sep 17 00:00:00 2001 From: Vasiliy Ermolovich Date: Tue, 6 Dec 2016 17:27:59 +0300 Subject: [PATCH 0258/3836] Make it possible to use dynamic names for scopes. Right now it's possible to pass a proc but it's evaluated outside of view context so it's not possible to use helper methods and stuff. --- features/index/index_scopes.feature | 19 +++++++++++++++++++ .../step_definitions/index_scope_steps.rb | 4 ++++ lib/active_admin/scope.rb | 3 +-- lib/active_admin/views/components/scopes.rb | 12 ++++++++++-- spec/unit/scope_spec.rb | 2 +- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/features/index/index_scopes.feature b/features/index/index_scopes.feature index e851e0d6855..550a66c0ad2 100644 --- a/features/index/index_scopes.feature +++ b/features/index/index_scopes.feature @@ -14,6 +14,25 @@ Feature: Index Scoping And I should see the scope "All" with the count 3 And I should see 3 posts in the table + Scenario: Viewing resources with one scope with dynamic name + Given 3 posts exist + And an index configuration of: + """ + ActiveAdmin.register Post do + scope -> { scope_title }, :all + + controller do + def scope_title + 'Neat scope' + end + + helper_method :scope_title + end + end + """ + Then I should see the scope with label "Neat scope" + And I should see 3 posts in the table + Scenario: Viewing resources with one scope as the default Given 3 posts exist And an index configuration of: diff --git a/features/step_definitions/index_scope_steps.rb b/features/step_definitions/index_scope_steps.rb index c45d9a489a7..4d785dd6785 100644 --- a/features/step_definitions/index_scope_steps.rb +++ b/features/step_definitions/index_scope_steps.rb @@ -14,6 +14,10 @@ step %{I should see "#{count}" within ".scopes .#{name} .count"} end +Then /^I should see the scope with label "([^"]*)"$/ do |label| + expect(page).to have_link(label) +end + Then /^I should see the scope "([^"]*)" with no count$/ do |name| name = name.tr(" ", "").underscore.downcase expect(page).to have_css ".scopes .#{name}" diff --git a/lib/active_admin/scope.rb b/lib/active_admin/scope.rb index b504d399c59..c653288ed61 100644 --- a/lib/active_admin/scope.rb +++ b/lib/active_admin/scope.rb @@ -46,10 +46,9 @@ def initialize(name, method = nil, options = {}, &block) def name case @name - when Proc then @name.call.to_s when String then @name when Symbol then @localizer ? @localizer.t(@name, scope: 'scopes') : @name.to_s.titleize - else @name.to_s + else @name end end diff --git a/lib/active_admin/views/components/scopes.rb b/lib/active_admin/views/components/scopes.rb index 972072167b4..b54c8c2b89f 100644 --- a/lib/active_admin/views/components/scopes.rb +++ b/lib/active_admin/views/components/scopes.rb @@ -31,10 +31,11 @@ def build(scopes, options = {}) def build_scope(scope, options) li class: classes_for_scope(scope) do - params = request.query_parameters.except :page, :scope, :commit, :format + scope_name = I18n.t "active_admin.scopes.#{scope.id}", default: name_for_scope(scope) + params = request.query_parameters.except :page, :scope, :commit, :format a href: url_for(scope: scope.id, params: params), class: 'table_tools_button' do - text_node scope.name + text_node scope_name span class: 'count' do "(#{get_scope_count(scope)})" end if options[:scope_count] && scope.show_count @@ -60,6 +61,13 @@ def current_scope?(scope) def get_scope_count(scope) collection_size(scope_chain(scope, collection_before_scope)) end + + def name_for_scope(scope) + case scope.name + when Proc then self.instance_exec(&scope.name).to_s + else scope.name.to_s + end + end end end end diff --git a/spec/unit/scope_spec.rb b/spec/unit/scope_spec.rb index 24349c524f6..77744f30986 100644 --- a/spec/unit/scope_spec.rb +++ b/spec/unit/scope_spec.rb @@ -135,7 +135,7 @@ it "should properly render the proc" do scope = ActiveAdmin::Scope.new proc{ Date.today.strftime '%A' }, :foobar - expect(scope.name).to eq Date.today.strftime '%A' + expect(scope.name.call).to eq Date.today.strftime '%A' end end From 9745ba5efeb35625563c5edc5cd113f8a25f5e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20G=C3=B6tze?= Date: Sat, 28 Jan 2017 18:41:47 +0100 Subject: [PATCH 0259/3836] Allow passing an Array to collection_size This allows you to use not only a ActiveRecord::Relation but also an Array as collection for code that calls ActiveAdmin::Helpers::Collection.collection_size. Passing an Array might be needed in case of creating a table on a custom page with a paginated array as collection. See https://github.com/activeadmin/activeadmin/issues/4423 --- lib/active_admin/helpers/collection.rb | 2 ++ spec/unit/helpers/collection_spec.rb | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/lib/active_admin/helpers/collection.rb b/lib/active_admin/helpers/collection.rb index ccacc7c1802..b8c53e7a353 100644 --- a/lib/active_admin/helpers/collection.rb +++ b/lib/active_admin/helpers/collection.rb @@ -4,6 +4,8 @@ module Collection # 1. removes `select` and `order` to prevent invalid SQL # 2. correctly handles the Hash returned when `group by` is used def collection_size(c = collection) + return c.count if c.is_a?(Array) + c = c.except :select, :order c.group_values.present? ? c.count.count : c.count diff --git a/spec/unit/helpers/collection_spec.rb b/spec/unit/helpers/collection_spec.rb index 77e3b5b2008..30cc227f5c2 100644 --- a/spec/unit/helpers/collection_spec.rb +++ b/spec/unit/helpers/collection_spec.rb @@ -32,6 +32,10 @@ expect(collection_size(Post.select("title, count(*) as nb_posts").group(:title).order("nb_posts"))).to eq 2 end + it "should return the collection size for an Array" do + expect(collection_size(Post.where(title: "A post").to_a)).to eq 2 + end + it "should take the defined collection by default" do def collection; Post.where(nil); end @@ -40,6 +44,10 @@ def collection; Post.where(nil); end def collection; Post.where(title: "An other post"); end expect(collection_size).to eq 1 + + def collection; Post.where(title: "A post").to_a end + + expect(collection_size).to eq 2 end end From a7db9a7eeec1f974694c965a4b6685412f2e6d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20G=C3=B6tze?= Date: Sat, 28 Jan 2017 19:43:28 +0100 Subject: [PATCH 0260/3836] Add Scenario for custom page with paginated array collection --- features/registering_pages.feature | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/features/registering_pages.feature b/features/registering_pages.feature index 85e789c13a3..355c461c205 100644 --- a/features/registering_pages.feature +++ b/features/registering_pages.feature @@ -146,3 +146,26 @@ Feature: Registering Pages And I follow "Check" Then I should see the content "Chocolate lØves You Too!" And I should see the Active Admin layout + + Scenario: Registering a page with paginated index table for a collection Array + Given a user named "John Doe" exists + Given a configuration of: + """ + ActiveAdmin.register_page "Special users" do + content do + collection = Kaminari.paginate_array(User.all).page(params.fetch(:page, 1)) + + table_for(collection, class: "index_table") do + column :first_name + column :last_name + end + + paginated_collection(collection, entry_name: "Special users") + end + end + """ + When I go to the dashboard + And I follow "Special users" + Then I should see the page title "Special users" + And I should see the Active Admin layout + And I should see 1 user in the table From aafdee7b8cb93248a28dff28dce3a87971b4ab55 Mon Sep 17 00:00:00 2001 From: Artur Borisovich Date: Mon, 19 Sep 2016 16:00:48 +0300 Subject: [PATCH 0261/3836] Added note about how to remove select on text input filter. --- docs/3-index-pages.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index 1be1063d428..f0effecc4db 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -100,6 +100,16 @@ the collection as a proc to be called at render time. filter :author, as: :check_boxes, collection: proc { Author.all } ``` +Also, if you don't need the select with the options 'contains', 'equals', 'starts_with' or 'ends_with' +just add the option to the filter name with an underscore. + +For example: +```ruby +filter :name_equals +# or +filter :name_contains +``` + You can change the filter label by passing a label option: ```ruby From 3731b25beda91c6cd281f943ea14aab6a24b9a3b Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sat, 28 Jan 2017 17:16:54 +0200 Subject: [PATCH 0262/3836] decorate_with should be part or resource dsl --- lib/active_admin/dsl.rb | 6 ------ lib/active_admin/resource_dsl.rb | 7 +++++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/active_admin/dsl.rb b/lib/active_admin/dsl.rb index a5438af28ec..dedf6073067 100644 --- a/lib/active_admin/dsl.rb +++ b/lib/active_admin/dsl.rb @@ -163,11 +163,5 @@ def sidebar(name, options = {}, &block) config.sidebar_sections << ActiveAdmin::SidebarSection.new(name, options, &block) end - def decorate_with(decorator_class) - # Force storage as a string. This will help us with reloading issues. - # Assuming decorator_class.to_s will return the name of the class allows - # us to handle a string or a class. - config.decorator_class_name = "::#{ decorator_class }" - end end end diff --git a/lib/active_admin/resource_dsl.rb b/lib/active_admin/resource_dsl.rb index 289e4580783..73ecb251d6f 100644 --- a/lib/active_admin/resource_dsl.rb +++ b/lib/active_admin/resource_dsl.rb @@ -130,6 +130,13 @@ def collection_action(name, options = {}, &block) action config.collection_actions, name, options, &block end + def decorate_with(decorator_class) + # Force storage as a string. This will help us with reloading issues. + # Assuming decorator_class.to_s will return the name of the class allows + # us to handle a string or a class. + config.decorator_class_name = "::#{ decorator_class }" + end + # Defined Callbacks # # == After Build From ed0e50c46253226f4ed022c9701e0f1f02f2e42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 12:40:32 -0300 Subject: [PATCH 0263/3836] Remove Rspec 2 stuff from jasmine config --- spec/javascripts/support/jasmine_config.rb | 16 ---------------- spec/javascripts/support/jasmine_runner.rb | 20 ++++---------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/spec/javascripts/support/jasmine_config.rb b/spec/javascripts/support/jasmine_config.rb index 47286f23055..56ceadb1f68 100644 --- a/spec/javascripts/support/jasmine_config.rb +++ b/spec/javascripts/support/jasmine_config.rb @@ -5,19 +5,3 @@ class Config end end - - -# Note - this is necessary for rspec2, which has removed the backtrace -module Jasmine - class SpecBuilder - def declare_spec(parent, spec) - me = self - example_name = spec["name"] - @spec_ids << spec["id"] - backtrace = @example_locations[parent.description + " " + example_name] - parent.it example_name, {} do - me.report_spec(spec["id"]) - end - end - end -end diff --git a/spec/javascripts/support/jasmine_runner.rb b/spec/javascripts/support/jasmine_runner.rb index 13ebce0cdd0..827ecfb7a68 100644 --- a/spec/javascripts/support/jasmine_runner.rb +++ b/spec/javascripts/support/jasmine_runner.rb @@ -2,31 +2,19 @@ require 'rubygems' require 'jasmine' -jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb')) -require jasmine_config_overrides if File.exist?(jasmine_config_overrides) -if Jasmine::rspec2? - require 'rspec' -else - require 'spec' -end +require 'spec' jasmine_config = Jasmine::Config.new spec_builder = Jasmine::SpecBuilder.new(jasmine_config) should_stop = false -if Jasmine::rspec2? - RSpec.configuration.after(:suite) do +Spec::Runner.configure do |config| + config.after(:suite) do spec_builder.stop if should_stop end -else - Spec::Runner.configure do |config| - config.after(:suite) do - spec_builder.stop if should_stop - end - end end spec_builder.start should_stop = true -spec_builder.declare_suites \ No newline at end of file +spec_builder.declare_suites From c2459ca0730303be865d4bf9c94d4b0bdc1a9481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 12:41:19 -0300 Subject: [PATCH 0264/3836] Remove unnecessary `require "rubygems"` --- spec/javascripts/support/jasmine_runner.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/javascripts/support/jasmine_runner.rb b/spec/javascripts/support/jasmine_runner.rb index 827ecfb7a68..ee23cc00c4e 100644 --- a/spec/javascripts/support/jasmine_runner.rb +++ b/spec/javascripts/support/jasmine_runner.rb @@ -1,6 +1,5 @@ $:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes -require 'rubygems' require 'jasmine' require 'spec' From 26252f2c60da123259ebbc188477fa57d456b7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 12:50:02 -0300 Subject: [PATCH 0265/3836] Remove empty file --- spec/javascripts/support/jasmine_config.rb | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 spec/javascripts/support/jasmine_config.rb diff --git a/spec/javascripts/support/jasmine_config.rb b/spec/javascripts/support/jasmine_config.rb deleted file mode 100644 index 56ceadb1f68..00000000000 --- a/spec/javascripts/support/jasmine_config.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Jasmine - class Config - - # Add your overrides or custom config code here - - end -end From b47291c09b125789ee26918c5b7f258761f2de62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 15:42:40 -0300 Subject: [PATCH 0266/3836] Tweak DB resetting in cucumber Use `trucation` strategy only for JS. --- features/support/env.rb | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/features/support/env.rb b/features/support/env.rb index eaf20d4daab..ca242de2476 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -72,35 +72,9 @@ # of your scenarios, as this makes it hard to discover errors in your application. ActionController::Base.allow_rescue = false -# If you set this to true, each scenario will run in a database transaction. -# You can still turn off transactions on a per-scenario basis, simply tagging -# a feature or scenario with the @no-txn tag. If you are using Capybara, -# tagging with @culerity or @javascript will also turn transactions off. -# -# If you set this to false, transactions will be off for all scenarios, -# regardless of whether you use @no-txn or not. -# -# Beware that turning transactions off will leave data in your database -# after each scenario, which can lead to hard-to-debug failures in -# subsequent scenarios. If you do this, we recommend you create a Before -# block that will explicitly put your database in a known state. -if ActiveAdmin::Dependency.rails5? - Cucumber::Rails::World.use_transactional_tests = true -else - Cucumber::Rails::World.use_transactional_fixtures = true -end - -# How to clean your database when transactions are turned off. See -# http://github.com/bmabey/database_cleaner for more info. -if defined?(ActiveRecord::Base) - begin - require 'database_cleaner' - require 'database_cleaner/cucumber' - DatabaseCleaner.strategy = :truncation - rescue LoadError - # ignore if database_cleaner isn't present - end -end +# Database resetting strategy +DatabaseCleaner.strategy = :truncation +Cucumber::Rails::Database.javascript_strategy = :truncation # Warden helpers to speed up login # See https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara From 2a7079a0c422edfd41df3606f0f9d2d2e4bbb529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 12 Sep 2016 02:11:30 -0300 Subject: [PATCH 0267/3836] Remove unnecessay LOAD_PATH manipulations --- features/support/env.rb | 3 +-- spec/spec_helper.rb | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/features/support/env.rb b/features/support/env.rb index ca242de2476..0fa42c176ed 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -23,8 +23,7 @@ require ENV['RAILS_ROOT'] + '/config/environment' -# Setup autoloading of ActiveAdmin and the load path -$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) +# Setup autoloading of ActiveAdmin autoload :ActiveAdmin, 'active_admin' require 'cucumber/rails' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c9467707126..ec32e7c6636 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,9 +1,6 @@ -$LOAD_PATH.unshift(File.dirname(__FILE__)) -$LOAD_PATH << File.expand_path('../support', __FILE__) - ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__) -require 'detect_rails_version' +require File.expand_path('../support/detect_rails_version', __FILE__) ENV['RAILS'] = detect_rails_version require 'simplecov' From 0eab1cc0c9933578382d8abec6726144609a711e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 12 Jan 2017 09:12:17 -0200 Subject: [PATCH 0268/3836] Don't skip git in the generated application This is useful so that the default gitignore file is generated in the subfolder, and greps are no longer polluted by the sample app logs, tmp and so on. --- script/local | 1 - tasks/test.rake | 1 - 2 files changed, 2 deletions(-) diff --git a/script/local b/script/local index 0e511d73183..f6a43f25d31 100755 --- a/script/local +++ b/script/local @@ -33,7 +33,6 @@ unless File.exist? path args = %w[ -m spec/support/rails_template_with_data.rb --skip-bundle - --skip-git --skip-listen --skip-turbolinks --skip-test-unit diff --git a/tasks/test.rake b/tasks/test.rake index 4cf96d53d25..2f6613fc4de 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -8,7 +8,6 @@ task :setup, :parallel do |t, opts| args = %w[ -m spec/support/rails_template.rb --skip-bundle - --skip-git --skip-listen --skip-turbolinks --skip-test-unit From c30dd563615e128fbe3ad97d15b988ac4a5b86fd Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Sun, 25 Sep 2016 14:38:09 -0600 Subject: [PATCH 0269/3836] Add the ability to customize the footer. By default, it will still default to the "Powered by Active Admin ", but this allows folks to customize that message. --- docs/1-general-configuration.md | 8 ++++++ features/footer.feature | 28 +++++++++++++++++++ features/step_definitions/footer_steps.rb | 11 ++++++++ lib/active_admin/application.rb | 3 ++ lib/active_admin/views/footer.rb | 20 +++++++++++-- lib/active_admin/views/pages/base.rb | 2 +- .../install/templates/active_admin.rb.erb | 7 +++++ 7 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 features/footer.feature create mode 100644 features/step_definitions/footer_steps.rb diff --git a/docs/1-general-configuration.md b/docs/1-general-configuration.md index a7798312088..18de6d147b8 100644 --- a/docs/1-general-configuration.md +++ b/docs/1-general-configuration.md @@ -169,3 +169,11 @@ ActiveAdmin.setup do |config| end end ``` + +## Footer Customization + +By default, Active Admin displays a "Powered by ActiveAdmin" message on every +page. You can override this message and show domain-specific messaging: +```ruby +config.footer = "MyApp Revision v1.3" +``` diff --git a/features/footer.feature b/features/footer.feature new file mode 100644 index 00000000000..1d7bbd866f2 --- /dev/null +++ b/features/footer.feature @@ -0,0 +1,28 @@ +Feature: Site title + + As a developer + In order to customize the site footer + I want to set it in the configuration + + Background: + Given I am logged in + + Scenario: No footer is set in the configuration (default) + When I am on the dashboard + And I should see the default footer + + Scenario: Set the footer in the configuration + Given a configuration of: + """ + ActiveAdmin.application.footer = "MyApp Revision 123" + """ + When I am on the dashboard + And I should see the footer "MyApp Revision 123" + + Scenario: Set the footer to a proc + Given a configuration of: + """ + ActiveAdmin.application.footer = proc { "Enjoy MyApp Revision 123, #{controller.current_admin_user.try(:email)}!" } + """ + When I am on the dashboard + And I should see the footer "Enjoy MyApp Revision 123, admin@example.com!" diff --git a/features/step_definitions/footer_steps.rb b/features/step_definitions/footer_steps.rb new file mode 100644 index 00000000000..6ba82fda0fb --- /dev/null +++ b/features/step_definitions/footer_steps.rb @@ -0,0 +1,11 @@ +Then /^I should see the default footer$/ do + expect(page).to have_css '#footer', text: "Powered by Active Admin #{ActiveAdmin::VERSION}" +end + +Then /^I should see the footer "([^"]*)"$/ do |footer| + expect(page).to have_css '#footer', text: footer +end + +Then /^I should not see the footer "([^"]*)"$/ do |footer| + expect(page).to_not have_css '#footer', text: footer +end diff --git a/lib/active_admin/application.rb b/lib/active_admin/application.rb index 6e8eb1772f2..5082c83c131 100644 --- a/lib/active_admin/application.rb +++ b/lib/active_admin/application.rb @@ -41,6 +41,9 @@ def initialize # Set the site title image displayed in the main layout (has precendence over :site_title) inheritable_setting :site_title_image, "" + # Set the site footer text (defaults to Powered by ActiveAdmin text with version) + inheritable_setting :footer, "" + # Set a favicon inheritable_setting :favicon, false diff --git a/lib/active_admin/views/footer.rb b/lib/active_admin/views/footer.rb index cf168516e36..c35be45c810 100644 --- a/lib/active_admin/views/footer.rb +++ b/lib/active_admin/views/footer.rb @@ -2,15 +2,29 @@ module ActiveAdmin module Views class Footer < Component - def build + def build(namespace) super id: "footer" - powered_by_message + @namespace = namespace + + if footer? + para footer_text + else + para powered_by_message + end + end + + def footer? + @namespace.footer.present? end private + def footer_text + helpers.render_or_call_method_or_proc_on(self, @namespace.footer) + end + def powered_by_message - para I18n.t('active_admin.powered_by', + I18n.t('active_admin.powered_by', active_admin: link_to("Active Admin", "http://www.activeadmin.info"), version: ActiveAdmin::VERSION).html_safe end diff --git a/lib/active_admin/views/pages/base.rb b/lib/active_admin/views/pages/base.rb index 1c796c829c4..0517159f021 100644 --- a/lib/active_admin/views/pages/base.rb +++ b/lib/active_admin/views/pages/base.rb @@ -138,7 +138,7 @@ def skip_sidebar? # Renders the content for the footer def build_footer - insert_tag view_factory.footer + insert_tag view_factory.footer, active_admin_namespace end end diff --git a/lib/generators/active_admin/install/templates/active_admin.rb.erb b/lib/generators/active_admin/install/templates/active_admin.rb.erb index a287b004bf8..c9a96d18971 100644 --- a/lib/generators/active_admin/install/templates/active_admin.rb.erb +++ b/lib/generators/active_admin/install/templates/active_admin.rb.erb @@ -269,4 +269,11 @@ ActiveAdmin.setup do |config| # of those filters by default here. # # config.include_default_association_filters = true + + # == Footer + # + # By default, the footer shows the current Active Admin version. You can + # override the content of the footer here. + # + # config.footer = 'my custom footer text' end From bcfc9e3739a18aba701ba259a5eb056b169a4c65 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Tue, 24 Jan 2017 03:08:01 +0200 Subject: [PATCH 0270/3836] order clause refactoring, allow to use custom sql ordering strategies - added ability to use custom class for handling ordering per resource eg ``` ActiveAdmin.register Post do config.order_clause = MyOrderClause end ``` - added dsl to customize ordering strategy per column eg ``` ActiveAdmin.register Post do order_by(:full_name) do |order_clause| ['COALESCE(NULLIF(last_name, ''), first_name), first_name', order_clause.order].join(' ') end end ``` --- CHANGELOG.md | 1 + docs/3-index-pages/index-as-table.md | 19 ++++++++++ lib/active_admin/application.rb | 3 ++ lib/active_admin/order_clause.rb | 36 ++++++++++++++---- lib/active_admin/resource.rb | 9 +++++ lib/active_admin/resource/ordering.rb | 11 ++++++ .../resource_controller/data_access.rb | 5 +-- lib/active_admin/resource_dsl.rb | 19 ++++++++++ .../views/components/table_for.rb | 2 +- .../install/templates/active_admin.rb.erb | 7 ++++ spec/unit/application_spec.rb | 4 ++ spec/unit/order_clause_spec.rb | 12 +++--- spec/unit/resource/ordering_spec.rb | 38 +++++++++++++++++++ .../resource_controller/data_access_spec.rb | 29 ++++++++++++++ 14 files changed, 178 insertions(+), 17 deletions(-) create mode 100644 lib/active_admin/resource/ordering.rb create mode 100644 spec/unit/resource/ordering_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b42dc6e8bc..a4a3c6084bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ #### Minor +* Support for custom sorting strategies [#4768][] by [@Fivell][] * Stream CSV downloads as they're generated [#3038][] by [@craigmcnamara][] * Disable streaming in development for easier debugging [#3535][] by [@seanlinsley][] * Improved code reloading [#3783][] by [@chancancode][] diff --git a/docs/3-index-pages/index-as-table.md b/docs/3-index-pages/index-as-table.md index 676cee8535f..284971a0c12 100644 --- a/docs/3-index-pages/index-as-table.md +++ b/docs/3-index-pages/index-as-table.md @@ -164,6 +164,24 @@ index do end ``` +## Custom sorting + +It is also possible to use database specific expressions and options for sorting by column + +```ruby +order_by(:title) do |order_clause| + if order_clause.order == 'desc' + [order_clause.to_sql, 'NULLS LAST'].join(' ') + else + [order_clause.to_sql, 'NULLS FIRST'].join(' ') + end +end + +index do + column :title +end +``` + ## Associated Sorting You're normally able to sort columns alphabetically, but by default you @@ -187,6 +205,7 @@ index do end ``` + ## Showing and Hiding Columns The entire index block is rendered within the context of the view, so you can diff --git a/lib/active_admin/application.rb b/lib/active_admin/application.rb index 5082c83c131..d55ee70f16a 100644 --- a/lib/active_admin/application.rb +++ b/lib/active_admin/application.rb @@ -107,6 +107,9 @@ def initialize # Whether to display 'Current Filters' on search screen inheritable_setting :current_filters, true + # class to handle ordering + inheritable_setting :order_clause, ActiveAdmin::OrderClause + # Request parameters that are permitted by default inheritable_setting :permitted_params, [ :utf8, :_method, :authenticity_token, :commit, :id diff --git a/lib/active_admin/order_clause.rb b/lib/active_admin/order_clause.rb index 5f0e93a610c..a8f1d86849e 100644 --- a/lib/active_admin/order_clause.rb +++ b/lib/active_admin/order_clause.rb @@ -1,13 +1,13 @@ module ActiveAdmin class OrderClause - attr_reader :field, :order + attr_reader :field, :order, :active_admin_config - def initialize(clause) + def initialize(active_admin_config, clause) clause =~ /^([\w\_\.]+)(->'\w+')?_(desc|asc)$/ @column = $1 @op = $2 @order = $3 - + @active_admin_config = active_admin_config @field = [@column, @op].compact.join end @@ -15,12 +15,34 @@ def valid? @field.present? && @order.present? end - def to_sql(active_admin_config) - table = active_admin_config.resource_column_names.include?(@column) ? active_admin_config.resource_table_name : nil - table_column = (@column =~ /\./) ? @column : - [table, active_admin_config.resource_quoted_column_name(@column)].compact.join(".") + def apply(chain) + chain.reorder(sql) + end + def to_sql [table_column, @op, ' ', @order].compact.join end + + def table + active_admin_config.resource_column_names.include?(@column) ? active_admin_config.resource_table_name : nil + end + + def table_column + (@column =~ /\./) ? @column : + [table, active_admin_config.resource_quoted_column_name(@column)].compact.join(".") + end + + def sql + custom_sql || to_sql + end + + protected + + def custom_sql + if active_admin_config.ordering[@column].present? + active_admin_config.ordering[@column].call(self) + end + end + end end diff --git a/lib/active_admin/resource.rb b/lib/active_admin/resource.rb index 8567825d7c3..b48abc52c37 100644 --- a/lib/active_admin/resource.rb +++ b/lib/active_admin/resource.rb @@ -10,6 +10,7 @@ require 'active_admin/resource/scope_to' require 'active_admin/resource/sidebars' require 'active_admin/resource/belongs_to' +require 'active_admin/resource/ordering' module ActiveAdmin @@ -50,6 +51,9 @@ def sort_order # Set breadcrumb builder attr_writer :breadcrumb + #Set order clause + attr_writer :order_clause + # Store a reference to the DSL so that we can dereference it during garbage collection. attr_accessor :dsl @@ -82,6 +86,7 @@ def initialize(namespace, resource_class, options = {}) include ScopeTo include Sidebars include Routes + include Ordering # The class this resource wraps. If you register the Post model, Resource#resource_class # will point to the Post class @@ -144,6 +149,10 @@ def breadcrumb instance_variable_defined?(:@breadcrumb) ? @breadcrumb : namespace.breadcrumb end + def order_clause + @order_clause || namespace.order_clause + end + def find_resource(id) resource = resource_class.public_send *method_for_find(id) (decorator_class && resource) ? decorator_class.new(resource) : resource diff --git a/lib/active_admin/resource/ordering.rb b/lib/active_admin/resource/ordering.rb new file mode 100644 index 00000000000..7248fad5aa1 --- /dev/null +++ b/lib/active_admin/resource/ordering.rb @@ -0,0 +1,11 @@ +module ActiveAdmin + class Resource + module Ordering + + def ordering + @ordering ||= {}.with_indifferent_access + end + + end + end +end diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index 48912346246..58ef3b50ab9 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -209,11 +209,10 @@ def apply_authorization_scope(collection) def apply_sorting(chain) params[:order] ||= active_admin_config.sort_order - - order_clause = OrderClause.new params[:order] + order_clause = active_admin_config.order_clause.new(active_admin_config, params[:order]) if order_clause.valid? - chain.reorder(order_clause.to_sql(active_admin_config)) + order_clause.apply(chain) else chain # just return the chain end diff --git a/lib/active_admin/resource_dsl.rb b/lib/active_admin/resource_dsl.rb index 73ecb251d6f..68b0308439f 100644 --- a/lib/active_admin/resource_dsl.rb +++ b/lib/active_admin/resource_dsl.rb @@ -8,6 +8,25 @@ def initialize(config, resource_class) private + # Redefine sort behaviour for column + # + # For example: + # + # # nulls last + # order_by(:age) do |order_clause| + # [order_clause.to_sql, 'NULLS LAST'].join(' ') if order_clause.order == 'desc' + # end + # + # # by last_name but in the case that there is no last name, by first_name. + # order_by(:full_name) do |order_clause| + # ['COALESCE(NULLIF(last_name, ''), first_name), first_name', order_clause.order].join(' ') + # end + # + # + def order_by(column, &block) + config.ordering[column] = block + end + def belongs_to(target, options = {}) config.belongs_to(target, options) end diff --git a/lib/active_admin/views/components/table_for.rb b/lib/active_admin/views/components/table_for.rb index 68a0a972a3b..fa392f24eec 100644 --- a/lib/active_admin/views/components/table_for.rb +++ b/lib/active_admin/views/components/table_for.rb @@ -109,7 +109,7 @@ def build_table_cell(col, resource) # current_sort[1] #=> asc | desc def current_sort @current_sort ||= begin - order_clause = OrderClause.new params[:order] + order_clause = active_admin_config.order_clause.new(active_admin_config, params[:order]) if order_clause.valid? [order_clause.field, order_clause.order] diff --git a/lib/generators/active_admin/install/templates/active_admin.rb.erb b/lib/generators/active_admin/install/templates/active_admin.rb.erb index c9a96d18971..a699d1d6aad 100644 --- a/lib/generators/active_admin/install/templates/active_admin.rb.erb +++ b/lib/generators/active_admin/install/templates/active_admin.rb.erb @@ -276,4 +276,11 @@ ActiveAdmin.setup do |config| # override the content of the footer here. # # config.footer = 'my custom footer text' + + # == Sorting + # + # By default ActiveAdmin::OrderClause is used for sorting logic + # You can inherit it with own class and inject it for all resources + # + # config.order_clause = MyOrderClause end diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index 59e7bcba1c4..7a0aae7ac14 100644 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -91,6 +91,10 @@ expect(application.comments).to eq true end + it "should have default order clause class" do + expect(application.order_clause).to eq ActiveAdmin::OrderClause + end + describe "authentication settings" do it "should have no default current_user_method" do diff --git a/spec/unit/order_clause_spec.rb b/spec/unit/order_clause_spec.rb index ab518f80f4b..db4da29befd 100644 --- a/spec/unit/order_clause_spec.rb +++ b/spec/unit/order_clause_spec.rb @@ -1,11 +1,11 @@ require 'rails_helper' describe ActiveAdmin::OrderClause do - subject { described_class.new clause } + subject { described_class.new(config, clause) } let(:application) { ActiveAdmin::Application.new } - let(:namespace) { ActiveAdmin::Namespace.new application, :admin } - let(:config) { ActiveAdmin::Resource.new namespace, Post } + let(:namespace) { ActiveAdmin::Namespace.new application, :admin } + let(:config) { ActiveAdmin::Resource.new namespace, Post } describe 'id_asc (existing column)' do let(:clause) { 'id_asc' } @@ -23,7 +23,7 @@ end specify '#to_sql prepends table name' do - expect(subject.to_sql(config)).to eq '"posts"."id" asc' + expect(subject.to_sql).to eq '"posts"."id" asc' end end @@ -43,7 +43,7 @@ end specify '#to_sql' do - expect(subject.to_sql(config)).to eq '"virtual_column" asc' + expect(subject.to_sql).to eq '"virtual_column" asc' end end @@ -63,7 +63,7 @@ end it 'converts to sql' do - expect(subject.to_sql(config)).to eq %Q("hstore_col"->'field' desc) + expect(subject.to_sql).to eq %Q("hstore_col"->'field' desc) end end diff --git a/spec/unit/resource/ordering_spec.rb b/spec/unit/resource/ordering_spec.rb new file mode 100644 index 00000000000..1a230172b26 --- /dev/null +++ b/spec/unit/resource/ordering_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' + +module ActiveAdmin + describe Resource, "Ordering" do + describe "#order_by" do + + let(:application) { ActiveAdmin::Application.new } + let(:namespace) { ActiveAdmin::Namespace.new application, :admin } + let(:resource_config) { ActiveAdmin::Resource.new namespace, Post } + let(:dsl){ ActiveAdmin::ResourceDSL.new(resource_config, Post) } + + it "should register the ordering in the config" do + dsl.run_registration_block do + order_by(:age) do |order_clause| + if order_clause.order == 'desc' + [order_clause.to_sql, 'NULLS LAST'].join(' ') + end + end + end + expect(resource_config.ordering.size).to eq(1) + end + + + it "should allow to setup custom ordering class" do + MyOrderClause = Class.new(ActiveAdmin::OrderClause) + dsl.run_registration_block do + config.order_clause = MyOrderClause + end + expect(resource_config.order_clause).to eq(MyOrderClause) + expect(application.order_clause).to eq(ActiveAdmin::OrderClause) + + end + + end + end +end + + diff --git a/spec/unit/resource_controller/data_access_spec.rb b/spec/unit/resource_controller/data_access_spec.rb index 5d268880465..5fbc781b330 100644 --- a/spec/unit/resource_controller/data_access_spec.rb +++ b/spec/unit/resource_controller/data_access_spec.rb @@ -60,6 +60,35 @@ end end + context "custom strategy" do + before do + expect(controller.send(:active_admin_config)).to receive(:ordering).twice.and_return( + { + published_date: proc do |order_clause| + [order_clause.to_sql, 'NULLS LAST'].join(' ') if order_clause.order == 'desc' + end + }.with_indifferent_access + ) + end + + context "when params applicable" do + let(:params) {{ order: "published_date_desc" }} + it "reorders chain" do + chain = double "ChainObj" + expect(chain).to receive(:reorder).with('"posts"."published_date" desc NULLS LAST').once.and_return(Post.search) + controller.send :apply_sorting, chain + end + end + context "when params not applicable" do + let(:params) {{ order: "published_date_asc" }} + it "reorders chain" do + chain = double "ChainObj" + expect(chain).to receive(:reorder).with('"posts"."published_date" asc').once.and_return(Post.search) + controller.send :apply_sorting, chain + end + end + end + end describe "scoping" do From f388c7a8be6e89c7894716bbdce75b18a415b967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 26 Jan 2017 09:52:02 -0200 Subject: [PATCH 0271/3836] Remove unecessary dependencies from Gemfile I guess those used to require pointing to master in the past, but that's no longer true. --- Gemfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index 13772b736c2..fb3737c3458 100644 --- a/Gemfile +++ b/Gemfile @@ -15,9 +15,7 @@ gem 'test-unit', '~> 3.0' if rails_major == '3' if rails_major == '5' # Note: when updating this list, be sure to also update the README - gem 'sass-rails', git: 'https://github.com/rails/sass-rails' gem 'inherited_resources', git: 'https://github.com/activeadmin/inherited_resources' - gem 'ransack', git: 'https://github.com/activerecord-hackery/ransack' end platform :ruby_19 do # Remove this block when we drop support for Ruby 1.9 From 0fdbe65b049dc4b6def73443e4a6bfbfd60779a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Sep 2016 19:26:17 -0300 Subject: [PATCH 0272/3836] Setup appraisal --- .gitignore | 1 + .travis.yml | 18 +++--- Appraisals | 90 ++++++++++++++++++++++++++++ CONTRIBUTING.md | 29 ++++----- Gemfile | 28 +-------- Rakefile | 8 --- features/support/env.rb | 4 +- gemfiles/rails_32.gemfile | 57 ++++++++++++++++++ gemfiles/rails_40.gemfile | 56 +++++++++++++++++ gemfiles/rails_41.gemfile | 56 +++++++++++++++++ gemfiles/rails_42.gemfile | 56 +++++++++++++++++ gemfiles/rails_50.gemfile | 49 +++++++++++++++ script/appraisal | 17 ++++++ script/local | 9 ++- script/use_rails | 53 ---------------- spec/rails_helper.rb | 5 +- spec/spec_helper.rb | 5 -- spec/support/detect_rails_version.rb | 34 ----------- tasks/test.rake | 30 +--------- 19 files changed, 415 insertions(+), 190 deletions(-) create mode 100644 Appraisals create mode 100644 gemfiles/rails_32.gemfile create mode 100644 gemfiles/rails_40.gemfile create mode 100644 gemfiles/rails_41.gemfile create mode 100644 gemfiles/rails_42.gemfile create mode 100644 gemfiles/rails_50.gemfile create mode 100755 script/appraisal delete mode 100755 script/use_rails delete mode 100644 spec/support/detect_rails_version.rb diff --git a/.gitignore b/.gitignore index acd70ed687e..120bafeee2e 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ pkg spec/rails *.sqlite3-journal Gemfile.lock +gemfiles/rails_[3-5][0-9].gemfile.lock Gemfile-*.lock capybara* viewcumber diff --git a/.travis.yml b/.travis.yml index 1d9f23c1009..259802eab6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,14 +27,14 @@ rvm: - 2.3.3 - 2.4.0 -env: - matrix: - - RAILS=3.2.22 - - RAILS=4.0.13 - - RAILS=4.1.16 - - RAILS=4.2.7.1 - - RAILS=5.0.1 +gemfile: + - gemfiles/rails_32.gemfile + - gemfiles/rails_40.gemfile + - gemfiles/rails_41.gemfile + - gemfiles/rails_42.gemfile + - gemfiles/rails_50.gemfile +env: global: - JRUBY_OPTS="-J-Xmx1024m --debug" @@ -43,7 +43,7 @@ matrix: exclude: - rvm: 1.9.3 - env: RAILS=5.0.1 + gemfile: gemfiles/rails_50.gemfile - rvm: 2.4.0 env: RAILS=3.2.22 @@ -56,7 +56,7 @@ matrix: allow_failures: - rvm: jruby-9.1.7.0 - env: RAILS=5.0.1 + gemfile: gemfiles/rails_50.gemfile - rvm: 2.4.0 env: RAILS=4.2.7.1 diff --git a/Appraisals b/Appraisals new file mode 100644 index 00000000000..24c0f190b3e --- /dev/null +++ b/Appraisals @@ -0,0 +1,90 @@ +appraise 'rails_32' do + gemspec + + gem 'rails', '3.2.22' + gem 'jquery-ui-rails', '~> 4.0' + gem 'devise', '~> 3.5' + + gem 'inherited_resources' + + gem 'test-unit', '~> 3.0' + + gem 'draper', '~> 2.1' + + platforms :ruby_19 do # Remove this block when we drop support for Ruby 1.9 + gem 'kaminari', '~> 0.15' + gem 'mime-types', '< 3' + gem 'nokogiri', '< 1.7' + gem 'public_suffix', '< 1.5' + end +end + +appraise 'rails_40' do + gemspec + + gem 'rails', '4.0.13' + gem 'jquery-ui-rails', '~> 5.0' + gem 'devise', '~> 3.5' + + gem 'inherited_resources' + + gem 'draper', '~> 2.1' + + platforms :ruby_19 do # Remove this block when we drop support for Ruby 1.9 + gem 'kaminari', '~> 0.15' + gem 'mime-types', '< 3' + gem 'nokogiri', '< 1.7' + gem 'public_suffix', '< 1.5' + end +end + +appraise 'rails_41' do + gemspec + + gem 'rails', '4.1.16' + gem 'jquery-ui-rails', '~> 5.0' + gem 'devise', '~> 3.5' + + gem 'inherited_resources' + + gem 'draper', '~> 2.1' + + platforms :ruby_19 do # Remove this block when we drop support for Ruby 1.9 + gem 'kaminari', '~> 0.15' + gem 'mime-types', '< 3' + gem 'nokogiri', '< 1.7' + gem 'public_suffix', '< 1.5' + end +end + +appraise 'rails_42' do + gemspec + + gem 'rails', '4.2.7.1' + gem 'jquery-ui-rails', '~> 5.0' + gem 'devise', '~> 3.5' + + gem 'inherited_resources' + + gem 'draper', '~> 2.1' + + platforms :ruby_19 do # Remove this block when we drop support for Ruby 1.9 + gem 'kaminari', '~> 0.15' + gem 'mime-types', '< 3' + gem 'nokogiri', '< 1.7' + gem 'public_suffix', '< 1.5' + end +end + +appraise 'rails_50' do + gemspec + + gem 'rails', '5.0.1' + gem 'jquery-ui-rails', '~> 5.0' + gem 'devise', '> 4.x' + + # Note: when updating this list, be sure to also update the README + gem 'inherited_resources', git: 'https://github.com/activeadmin/inherited_resources' + + gem 'draper', '> 3.x' +end diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68546b6b0d1..2fdbcb64b8a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,21 +29,26 @@ git checkout -b 325-add-japanese-translations Install the development dependencies: ```sh -bundle install +script/appraisal install ``` Now you should be able to run the entire suite using: ```sh -rake test +script/appraisal rails_50 rake test ``` -Which will generate a rails application in `spec/rails` to run the tests against. +NOTE: You can also use `rails_42` or the other Rails versions defined in the +`Appraisals` file, but initial focus on the latest supported Rails version is +preferred. + +The previous command will generate a rails application in `spec/rails` to run +the tests against. If your tests are passing locally but they're failing on Travis, reset your test environment: ```sh -rm -rf spec/rails && bundle update +rm -rf spec/rails && script/appraisal update ``` ### 4. Implement your fix or feature @@ -59,20 +64,12 @@ a look at your changes in a browser. To boot up a test Rails app: ```sh -script/local server +script/appraisal rails_50 script/local server ``` This will automatically create a Rails app if none already exists, and store it in the `.test-rails-apps` folder. The currently active app is symlinked to `test-rails-app`. -If you have any Bundler issues, call the `use_rails` script then prepend -the version of rails you would like to use in an environment variable: - -```sh -script/use_rails 4.0.0 -RAILS=4.0.0 script/local server -``` - You should now be able to open in your browser. You can log in using: User: admin@example.com @@ -84,13 +81,13 @@ If you need to perform any other commands on the test application, use the To boot the rails console: ```sh -script/local console +script/appraisal rails_50 script/local console ``` Or to migrate the database: ```sh -script/local rake db:migrate +script/appraisal rails_50 script/local rake db:migrate ``` ### 6. Run tests against major supported rails versions @@ -99,7 +96,7 @@ Once you've implemented your code, got the tests passing, previewed it in a browser, you're ready to test it against multiple versions of Rails. ```sh -rake test:major_supported_rails +script/appraisal rake test ``` This runs our test suite against a couple of major versions of Rails. diff --git a/Gemfile b/Gemfile index fb3737c3458..62fd612707e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,35 +1,9 @@ source 'https://rubygems.org' -gemspec - -require File.expand_path 'spec/support/detect_rails_version', File.dirname(__FILE__) - -rails_version = detect_rails_version -rails_major = rails_version[0] - -gem 'rails', rails_version - -gem 'jquery-ui-rails', rails_major == '3' ? '~> 4.0' : '~> 5.0' - -gem 'test-unit', '~> 3.0' if rails_major == '3' - -if rails_major == '5' - # Note: when updating this list, be sure to also update the README - gem 'inherited_resources', git: 'https://github.com/activeadmin/inherited_resources' -end - -platform :ruby_19 do # Remove this block when we drop support for Ruby 1.9 - gem 'kaminari', '~> 0.15' - gem 'mime-types', '< 3' - gem 'nokogiri', '< 1.7' - gem 'public_suffix', '< 1.5' -end - +gem 'appraisal' # Optional dependencies gem 'cancan' -gem 'devise', rails_major == '5' ? '> 4.x' : '~> 3.5' -gem 'draper', rails_major == '5' ? '> 3.x' : '~> 2.1' gem 'pundit' # Until https://github.com/erikhuda/thor/issues/538 fixed diff --git a/Rakefile b/Rakefile index 1fe83932c7c..1c69f329e70 100644 --- a/Rakefile +++ b/Rakefile @@ -1,13 +1,5 @@ -require 'bundler/setup' require 'bundler/gem_tasks' -def cmd(command) - puts command - fail unless system command -end - -require File.expand_path('../spec/support/detect_rails_version', __FILE__) - # Import all our rake tasks FileList['tasks/**/*.rake'].each { |task| import task } diff --git a/features/support/env.rb b/features/support/env.rb index 0fa42c176ed..18c3a2c7360 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -8,14 +8,14 @@ require File.expand_path('../../../spec/spec_helper', __FILE__) -ENV['RAILS_ROOT'] = File.expand_path("../../../spec/rails/rails-#{ENV["RAILS"]}", __FILE__) +require 'rails' +ENV['RAILS_ROOT'] = File.expand_path("../../../spec/rails/rails-#{Rails.version}", __FILE__) # Create the test app if it doesn't exists unless File.exists?(ENV['RAILS_ROOT']) system 'rake setup' end -require 'rails' require 'active_record' require 'active_admin' require 'devise' diff --git a/gemfiles/rails_32.gemfile b/gemfiles/rails_32.gemfile new file mode 100644 index 00000000000..27d61107f5c --- /dev/null +++ b/gemfiles/rails_32.gemfile @@ -0,0 +1,57 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "cancan" +gem "pundit" +gem "thor", "<= 0.19.1" +gem "rake" +gem "parallel_tests", "< 2.10" +gem "pry" +gem "rails", "3.2.22" +gem "jquery-ui-rails", "~> 4.0" +gem "devise", "~> 3.5" +gem "inherited_resources" +gem "test-unit", "~> 3.0" +gem "draper", "~> 2.1" + +group :development do + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "binding_of_caller", :platforms => :mri + gem "rack-mini-profiler" + gem "flamegraph", :platforms => :mri + gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false + gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false + gem "yard" + gem "redcarpet", :platforms => :mri + gem "kramdown", :platforms => :jruby +end + +group :test do + gem "capybara" + gem "simplecov", :require => false + gem "codecov", :require => false + gem "cucumber-rails", :require => false + gem "cucumber", "1.3.20" + gem "database_cleaner" + gem "jasmine" + gem "jslint_on_rails" + gem "launchy" + gem "rails-i18n" + gem "rspec-rails" + gem "i18n-spec" + gem "shoulda-matchers", "<= 2.8.0" + gem "sqlite3", :platforms => :mri + gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby + gem "poltergeist" +end + +platforms :ruby_19 do + gem "kaminari", "~> 0.15" + gem "mime-types", "< 3" + gem "nokogiri", "< 1.7" + gem "public_suffix", "< 1.5" +end + +gemspec :path => "../" diff --git a/gemfiles/rails_40.gemfile b/gemfiles/rails_40.gemfile new file mode 100644 index 00000000000..d002b979c39 --- /dev/null +++ b/gemfiles/rails_40.gemfile @@ -0,0 +1,56 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "cancan" +gem "pundit" +gem "thor", "<= 0.19.1" +gem "rake" +gem "parallel_tests", "< 2.10" +gem "pry" +gem "rails", "4.0.13" +gem "jquery-ui-rails", "~> 5.0" +gem "devise", "~> 3.5" +gem "inherited_resources" +gem "draper", "~> 2.1" + +group :development do + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "binding_of_caller", :platforms => :mri + gem "rack-mini-profiler" + gem "flamegraph", :platforms => :mri + gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false + gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false + gem "yard" + gem "redcarpet", :platforms => :mri + gem "kramdown", :platforms => :jruby +end + +group :test do + gem "capybara" + gem "simplecov", :require => false + gem "codecov", :require => false + gem "cucumber-rails", :require => false + gem "cucumber", "1.3.20" + gem "database_cleaner" + gem "jasmine" + gem "jslint_on_rails" + gem "launchy" + gem "rails-i18n" + gem "rspec-rails" + gem "i18n-spec" + gem "shoulda-matchers", "<= 2.8.0" + gem "sqlite3", :platforms => :mri + gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby + gem "poltergeist" +end + +platforms :ruby_19 do + gem "kaminari", "~> 0.15" + gem "mime-types", "< 3" + gem "nokogiri", "< 1.7" + gem "public_suffix", "< 1.5" +end + +gemspec :path => "../" diff --git a/gemfiles/rails_41.gemfile b/gemfiles/rails_41.gemfile new file mode 100644 index 00000000000..94744697f79 --- /dev/null +++ b/gemfiles/rails_41.gemfile @@ -0,0 +1,56 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "cancan" +gem "pundit" +gem "thor", "<= 0.19.1" +gem "rake" +gem "parallel_tests", "< 2.10" +gem "pry" +gem "rails", "4.1.16" +gem "jquery-ui-rails", "~> 5.0" +gem "devise", "~> 3.5" +gem "inherited_resources" +gem "draper", "~> 2.1" + +group :development do + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "binding_of_caller", :platforms => :mri + gem "rack-mini-profiler" + gem "flamegraph", :platforms => :mri + gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false + gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false + gem "yard" + gem "redcarpet", :platforms => :mri + gem "kramdown", :platforms => :jruby +end + +group :test do + gem "capybara" + gem "simplecov", :require => false + gem "codecov", :require => false + gem "cucumber-rails", :require => false + gem "cucumber", "1.3.20" + gem "database_cleaner" + gem "jasmine" + gem "jslint_on_rails" + gem "launchy" + gem "rails-i18n" + gem "rspec-rails" + gem "i18n-spec" + gem "shoulda-matchers", "<= 2.8.0" + gem "sqlite3", :platforms => :mri + gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby + gem "poltergeist" +end + +platforms :ruby_19 do + gem "kaminari", "~> 0.15" + gem "mime-types", "< 3" + gem "nokogiri", "< 1.7" + gem "public_suffix", "< 1.5" +end + +gemspec :path => "../" diff --git a/gemfiles/rails_42.gemfile b/gemfiles/rails_42.gemfile new file mode 100644 index 00000000000..318cfcaa0f4 --- /dev/null +++ b/gemfiles/rails_42.gemfile @@ -0,0 +1,56 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "cancan" +gem "pundit" +gem "thor", "<= 0.19.1" +gem "rake" +gem "parallel_tests", "< 2.10" +gem "pry" +gem "rails", "4.2.7.1" +gem "jquery-ui-rails", "~> 5.0" +gem "devise", "~> 3.5" +gem "inherited_resources" +gem "draper", "~> 2.1" + +group :development do + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "binding_of_caller", :platforms => :mri + gem "rack-mini-profiler" + gem "flamegraph", :platforms => :mri + gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false + gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false + gem "yard" + gem "redcarpet", :platforms => :mri + gem "kramdown", :platforms => :jruby +end + +group :test do + gem "capybara" + gem "simplecov", :require => false + gem "codecov", :require => false + gem "cucumber-rails", :require => false + gem "cucumber", "1.3.20" + gem "database_cleaner" + gem "jasmine" + gem "jslint_on_rails" + gem "launchy" + gem "rails-i18n" + gem "rspec-rails" + gem "i18n-spec" + gem "shoulda-matchers", "<= 2.8.0" + gem "sqlite3", :platforms => :mri + gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby + gem "poltergeist" +end + +platforms :ruby_19 do + gem "kaminari", "~> 0.15" + gem "mime-types", "< 3" + gem "nokogiri", "< 1.7" + gem "public_suffix", "< 1.5" +end + +gemspec :path => "../" diff --git a/gemfiles/rails_50.gemfile b/gemfiles/rails_50.gemfile new file mode 100644 index 00000000000..10393defe6f --- /dev/null +++ b/gemfiles/rails_50.gemfile @@ -0,0 +1,49 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal" +gem "cancan" +gem "pundit" +gem "thor", "<= 0.19.1" +gem "rake" +gem "parallel_tests", "< 2.10" +gem "pry" +gem "rails", "5.0.1" +gem "jquery-ui-rails", "~> 5.0" +gem "devise", "> 4.x" +gem "inherited_resources", :git => "https://github.com/activeadmin/inherited_resources" +gem "draper", "> 3.x" + +group :development do + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "binding_of_caller", :platforms => :mri + gem "rack-mini-profiler" + gem "flamegraph", :platforms => :mri + gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false + gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false + gem "yard" + gem "redcarpet", :platforms => :mri + gem "kramdown", :platforms => :jruby +end + +group :test do + gem "capybara" + gem "simplecov", :require => false + gem "codecov", :require => false + gem "cucumber-rails", :require => false + gem "cucumber", "1.3.20" + gem "database_cleaner" + gem "jasmine" + gem "jslint_on_rails" + gem "launchy" + gem "rails-i18n" + gem "rspec-rails" + gem "i18n-spec" + gem "shoulda-matchers", "<= 2.8.0" + gem "sqlite3", :platforms => :mri + gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby + gem "poltergeist" +end + +gemspec :path => "../" diff --git a/script/appraisal b/script/appraisal new file mode 100755 index 00000000000..eac3249f71f --- /dev/null +++ b/script/appraisal @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'appraisal' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("appraisal", "appraisal") diff --git a/script/local b/script/local index f6a43f25d31..5a2edbeaefa 100755 --- a/script/local +++ b/script/local @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'shellwords' -require File.expand_path('../../spec/support/detect_rails_version', __FILE__) unless ARGV[0] puts <<-EOF @@ -19,11 +18,11 @@ Examples: exit(1) end -# Set up some variables -rails_version = detect_rails_version! +require 'rails' +# Set up some variables dir = ".test-rails-apps" -path = "#{dir}/test-rails-app-#{rails_version}" +path = "#{dir}/test-rails-app-#{Rails.version}" # Ensure .test-rails-apps is created system "mkdir #{dir}" unless File.exist?(dir) @@ -37,7 +36,7 @@ unless File.exist? path --skip-turbolinks --skip-test-unit ] - system "RAILS='#{rails_version}' rails new #{Shellwords.escape path} #{args.join ' '}" + system "rails new #{Shellwords.escape path} #{args.join ' '}" end # Link this rails app diff --git a/script/use_rails b/script/use_rails deleted file mode 100755 index fcf0ff079af..00000000000 --- a/script/use_rails +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env ruby -# -# Switches the development environment to use the given -# version of rails. Caches the Gemfile.locks so that -# switching it very fast. -# -require File.expand_path("../../spec/support/detect_rails_version", __FILE__) - -def cmd(command) - puts command - exit 1 unless system command -end - -version = ARGV[0] - -unless version - puts "USAGE: ./script/#{__FILE__} VERSION [OPTIONS]" - puts - puts "Options:" - puts " --clobber Add this flag to remove the existing Gemfile.lock before running" - exit(1) -end - -def file_or_symlink?(path) - File.exist?(path) || File.symlink?(path) -end - -gem_lock_dir = ".gemfile-locks" -gem_lock_file = "#{gem_lock_dir}/Gemfile-#{version}.lock" - -# Ensure our lock dir is created -cmd "mkdir #{gem_lock_dir}" unless File.exists?(gem_lock_dir) - -# --clobber passed in -if File.exists?(gem_lock_file) && ARGV.include?('--clobber') - cmd "rm #{gem_lock_file}" -end - -write_rails_version(version) - -# Ensure that bundler installs -ENV['RUBYOPT'] = '' - -if File.exists?(gem_lock_file) - cmd("rm Gemfile.lock") if file_or_symlink?("Gemfile.lock") - cmd("ln -s #{gem_lock_file} Gemfile.lock") - cmd("bundle") -else - cmd "rm Gemfile.lock" if file_or_symlink?("Gemfile.lock") - cmd "bundle install" - cmd "mv Gemfile.lock #{gem_lock_file}" - cmd("ln -s #{gem_lock_file} Gemfile.lock") -end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index b15f7cd7bef..f162f4c1181 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -89,14 +89,15 @@ def with_translation(translation) end ENV['RAILS_ENV'] = 'test' -ENV['RAILS_ROOT'] = File.expand_path("../rails/rails-#{ENV['RAILS']}", __FILE__) + +require 'rails' +ENV['RAILS_ROOT'] = File.expand_path("../rails/rails-#{Rails.version}", __FILE__) # Create the test app if it doesn't exists unless File.exists?(ENV['RAILS_ROOT']) system 'rake setup' end -require 'rails' require 'active_record' require 'active_admin' require 'devise' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ec32e7c6636..1896e176791 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,3 @@ -ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__) - -require File.expand_path('../support/detect_rails_version', __FILE__) -ENV['RAILS'] = detect_rails_version - require 'simplecov' SimpleCov.start do diff --git a/spec/support/detect_rails_version.rb b/spec/support/detect_rails_version.rb deleted file mode 100644 index 67895fba372..00000000000 --- a/spec/support/detect_rails_version.rb +++ /dev/null @@ -1,34 +0,0 @@ -# Detects the current version of Rails that is being used -# -# -RAILS_VERSION_FILE ||= File.expand_path("../../../.rails-version", __FILE__) - -unless defined? TRAVIS_CONFIG - require 'yaml' - filename = File.expand_path("../../../.travis.yml", __FILE__) - TRAVIS_CONFIG = YAML.load_file filename - TRAVIS_RAILS_VERSIONS = TRAVIS_CONFIG['env']['matrix'].grep(/RAILS=(.*)/){ $1 }.map{ |v| v.delete('"') } -end - -DEFAULT_RAILS_VERSION ||= TRAVIS_RAILS_VERSIONS.last - -def detect_rails_version - version = version_from_file || ENV['RAILS'] || DEFAULT_RAILS_VERSION -ensure - puts "Detected Rails: #{version}" if ENV['DEBUG'] -end - -def detect_rails_version! - detect_rails_version or raise "can't find a version of Rails to use!" -end - -def version_from_file - if File.exists?(RAILS_VERSION_FILE) - version = File.read(RAILS_VERSION_FILE).chomp.strip - version unless version == '' - end -end - -def write_rails_version(version) - File.open(RAILS_VERSION_FILE, "w+"){|f| f << version } -end diff --git a/tasks/test.rake b/tasks/test.rake index 2f6613fc4de..9fed5b6af1b 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,7 +1,7 @@ desc "Creates a test rails app for the specs to run against" task :setup, :parallel do |t, opts| require 'rails/version' - if File.exist? dir = "spec/rails/rails-#{Shellwords.escape detect_rails_version}" + if File.exist? dir = "spec/rails/rails-#{Rails::VERSION::STRING}" puts "test app #{dir} already exists; skipping" else system 'mkdir -p spec/rails' @@ -20,34 +20,6 @@ end desc "Run the full suite using 1 core" task test: ['spec:unit', 'spec:request', 'cucumber', 'cucumber:class_reloading'] -namespace :test do - - def run_tests_against(*versions) - current_version = detect_rails_version if File.exists?("Gemfile.lock") - - versions.each do |version| - puts - puts "== Using Rails #{version}" - - cmd "./script/use_rails #{version}" - cmd "bundle exec rspec spec" - cmd "bundle exec cucumber features" - cmd "bundle exec cucumber -p class-reloading features" - end - - cmd "./script/use_rails #{current_version}" if current_version - end - - desc "Run the full suite against the important versions of rails" - task :major_supported_rails do - run_tests_against *TRAVIS_RAILS_VERSIONS - end - - desc "Alias for major_supported_rails" - task all: :major_supported_rails - -end - require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) From b2f6f9a385387f8c34c4e2e0cea5d6aa318cf724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Sep 2016 20:40:48 -0300 Subject: [PATCH 0273/3836] Remove unexistent files from gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 120bafeee2e..1652eac86b6 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,6 @@ spec/rails *.sqlite3-journal Gemfile.lock gemfiles/rails_[3-5][0-9].gemfile.lock -Gemfile-*.lock capybara* viewcumber test-rails* From 3cb2bcd22cf95b56c78fc3a086c731f003a5abf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 26 Jan 2017 19:45:41 -0200 Subject: [PATCH 0274/3836] Bump bundler in Travis to 1.14.3 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 259802eab6d..525271ceea5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_install: - source script/install_phantomjs.sh - gem update --system # use the very latest Rubygems - rvm @global do gem uninstall bundler -a -x - - rvm @global do gem install bundler -v 1.14.2 # latest version known to work + - rvm @global do gem install bundler -v 1.14.3 # latest version known to work before_script: - bundle exec rake setup From ccf3f6b97743ce5ac61599653dd3d5cf1d767607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 30 Jan 2017 10:41:39 -0200 Subject: [PATCH 0275/3836] Check versions like everywhere else in that file Otherwise I get errors because AA has not yet been required at that point. --- spec/support/rails_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 4b64afcac16..c08b0aa86a9 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -129,7 +129,7 @@ class Tagging < ActiveRecord::Base config.action_mailer.default_url_options = {host: 'example.com'} config.assets.digest = false - if ActiveAdmin::Dependency.rails? '>= 4.1.0' + if Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR >= 1 config.active_record.maintain_test_schema = false end From e0f37d8db00f6ff2a44bf3442fa28aec38d79d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 30 Jan 2017 21:22:55 -0200 Subject: [PATCH 0276/3836] Move appraisal gem into development group And make sure it's not automatically required. We are experiencing segfaults during CI builds with ruby 2.4.0 inside appraisal code. Appraisal is, however, not necessary for those builds since Travis simply sets the `BUNDLE_GEMFILE` environment variable. So I made sure Appraisal is not actually used there. We don't need to worry about this in development since when Appraisal is actually used (gemfile management, running tests against a specific Rails version without using BUNDLE_GEMFILE directly), it'll run directly (through appraisal binstub). We should report the crash to Appraisal, though, so they can investigate and forward it upstream if it happens to be a Ruby bug. It's happing in an `instance_eval`, so a wild guess could be https://bugs.ruby-lang.org/issues/13090. --- Gemfile | 3 +-- gemfiles/rails_32.gemfile | 2 +- gemfiles/rails_40.gemfile | 2 +- gemfiles/rails_41.gemfile | 2 +- gemfiles/rails_42.gemfile | 2 +- gemfiles/rails_50.gemfile | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 62fd612707e..689057310e6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,5 @@ source 'https://rubygems.org' -gem 'appraisal' - # Optional dependencies gem 'cancan' gem 'pundit' @@ -35,6 +33,7 @@ group :development do gem 'yard' # Documentation generator gem 'redcarpet', platforms: :mri # Markdown implementation (for yard) gem 'kramdown', platforms: :jruby # Markdown implementation (for yard) + gem 'appraisal', require: false end group :test do diff --git a/gemfiles/rails_32.gemfile b/gemfiles/rails_32.gemfile index 27d61107f5c..14fc4ba4219 100644 --- a/gemfiles/rails_32.gemfile +++ b/gemfiles/rails_32.gemfile @@ -2,7 +2,6 @@ source "https://rubygems.org" -gem "appraisal" gem "cancan" gem "pundit" gem "thor", "<= 0.19.1" @@ -26,6 +25,7 @@ group :development do gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby + gem "appraisal", :require => false end group :test do diff --git a/gemfiles/rails_40.gemfile b/gemfiles/rails_40.gemfile index d002b979c39..ef0651d2ef5 100644 --- a/gemfiles/rails_40.gemfile +++ b/gemfiles/rails_40.gemfile @@ -2,7 +2,6 @@ source "https://rubygems.org" -gem "appraisal" gem "cancan" gem "pundit" gem "thor", "<= 0.19.1" @@ -25,6 +24,7 @@ group :development do gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby + gem "appraisal", :require => false end group :test do diff --git a/gemfiles/rails_41.gemfile b/gemfiles/rails_41.gemfile index 94744697f79..edd00ec8c56 100644 --- a/gemfiles/rails_41.gemfile +++ b/gemfiles/rails_41.gemfile @@ -2,7 +2,6 @@ source "https://rubygems.org" -gem "appraisal" gem "cancan" gem "pundit" gem "thor", "<= 0.19.1" @@ -25,6 +24,7 @@ group :development do gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby + gem "appraisal", :require => false end group :test do diff --git a/gemfiles/rails_42.gemfile b/gemfiles/rails_42.gemfile index 318cfcaa0f4..81e618827b8 100644 --- a/gemfiles/rails_42.gemfile +++ b/gemfiles/rails_42.gemfile @@ -2,7 +2,6 @@ source "https://rubygems.org" -gem "appraisal" gem "cancan" gem "pundit" gem "thor", "<= 0.19.1" @@ -25,6 +24,7 @@ group :development do gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby + gem "appraisal", :require => false end group :test do diff --git a/gemfiles/rails_50.gemfile b/gemfiles/rails_50.gemfile index 10393defe6f..82f44c4c25b 100644 --- a/gemfiles/rails_50.gemfile +++ b/gemfiles/rails_50.gemfile @@ -2,7 +2,6 @@ source "https://rubygems.org" -gem "appraisal" gem "cancan" gem "pundit" gem "thor", "<= 0.19.1" @@ -25,6 +24,7 @@ group :development do gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby + gem "appraisal", :require => false end group :test do From 16a7caacd2ffeefedbea1bb2f97fb7602cfa72a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 30 Jan 2017 22:24:05 -0200 Subject: [PATCH 0277/3836] Remove some unused dependencies --- Gemfile | 5 ----- gemfiles/rails_32.gemfile | 3 --- gemfiles/rails_40.gemfile | 3 --- gemfiles/rails_41.gemfile | 3 --- gemfiles/rails_42.gemfile | 3 --- gemfiles/rails_50.gemfile | 3 --- 6 files changed, 20 deletions(-) diff --git a/Gemfile b/Gemfile index 689057310e6..73ac53ea563 100644 --- a/Gemfile +++ b/Gemfile @@ -23,11 +23,6 @@ group :development do # Performance gem 'rack-mini-profiler' # Inline app profiler. See ?pp=help for options. - gem 'flamegraph', platforms: :mri # Flamegraph visualiztion: ?pp=flamegraph - - # Flamegraph dependency - gem 'stackprof', platforms: [:mri_21, :mri_22, :mri_23], require: false - gem 'fast_stack', platforms: [:mri_19, :mri_20], require: false # Documentation gem 'yard' # Documentation generator diff --git a/gemfiles/rails_32.gemfile b/gemfiles/rails_32.gemfile index 14fc4ba4219..56f07e663c7 100644 --- a/gemfiles/rails_32.gemfile +++ b/gemfiles/rails_32.gemfile @@ -19,9 +19,6 @@ group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" - gem "flamegraph", :platforms => :mri - gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false - gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby diff --git a/gemfiles/rails_40.gemfile b/gemfiles/rails_40.gemfile index ef0651d2ef5..5b705cee3b5 100644 --- a/gemfiles/rails_40.gemfile +++ b/gemfiles/rails_40.gemfile @@ -18,9 +18,6 @@ group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" - gem "flamegraph", :platforms => :mri - gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false - gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby diff --git a/gemfiles/rails_41.gemfile b/gemfiles/rails_41.gemfile index edd00ec8c56..ae40726a102 100644 --- a/gemfiles/rails_41.gemfile +++ b/gemfiles/rails_41.gemfile @@ -18,9 +18,6 @@ group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" - gem "flamegraph", :platforms => :mri - gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false - gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby diff --git a/gemfiles/rails_42.gemfile b/gemfiles/rails_42.gemfile index 81e618827b8..9eda442e3f3 100644 --- a/gemfiles/rails_42.gemfile +++ b/gemfiles/rails_42.gemfile @@ -18,9 +18,6 @@ group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" - gem "flamegraph", :platforms => :mri - gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false - gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby diff --git a/gemfiles/rails_50.gemfile b/gemfiles/rails_50.gemfile index 82f44c4c25b..51e416a97b9 100644 --- a/gemfiles/rails_50.gemfile +++ b/gemfiles/rails_50.gemfile @@ -18,9 +18,6 @@ group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" - gem "flamegraph", :platforms => :mri - gem "stackprof", :platforms => [:mri_21, :mri_22, :mri_23], :require => false - gem "fast_stack", :platforms => [:mri_19, :mri_20], :require => false gem "yard" gem "redcarpet", :platforms => :mri gem "kramdown", :platforms => :jruby From 078cc4646752d7b37fa85055a86c613ab263d85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 30 Jan 2017 21:28:04 -0200 Subject: [PATCH 0278/3836] Add missing `ruby_24` Gemfile declaration --- Gemfile | 2 +- gemfiles/rails_32.gemfile | 2 +- gemfiles/rails_40.gemfile | 2 +- gemfiles/rails_41.gemfile | 2 +- gemfiles/rails_42.gemfile | 2 +- gemfiles/rails_50.gemfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 73ac53ea563..cf4177e8469 100644 --- a/Gemfile +++ b/Gemfile @@ -17,7 +17,7 @@ gem 'pry' # Easily debug from your console wit group :development do # Debugging gem 'better_errors', # Web UI to debug exceptions. Go to /__better_errors to access the latest one - platforms: [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + platforms: [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] gem 'binding_of_caller', platforms: :mri # Retrieve the binding of a method's caller in MRI Ruby >= 1.9.2 diff --git a/gemfiles/rails_32.gemfile b/gemfiles/rails_32.gemfile index 56f07e663c7..046a26e39ed 100644 --- a/gemfiles/rails_32.gemfile +++ b/gemfiles/rails_32.gemfile @@ -16,7 +16,7 @@ gem "test-unit", "~> 3.0" gem "draper", "~> 2.1" group :development do - gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" gem "yard" diff --git a/gemfiles/rails_40.gemfile b/gemfiles/rails_40.gemfile index 5b705cee3b5..0326df20979 100644 --- a/gemfiles/rails_40.gemfile +++ b/gemfiles/rails_40.gemfile @@ -15,7 +15,7 @@ gem "inherited_resources" gem "draper", "~> 2.1" group :development do - gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" gem "yard" diff --git a/gemfiles/rails_41.gemfile b/gemfiles/rails_41.gemfile index ae40726a102..acb75943718 100644 --- a/gemfiles/rails_41.gemfile +++ b/gemfiles/rails_41.gemfile @@ -15,7 +15,7 @@ gem "inherited_resources" gem "draper", "~> 2.1" group :development do - gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" gem "yard" diff --git a/gemfiles/rails_42.gemfile b/gemfiles/rails_42.gemfile index 9eda442e3f3..7169b773fe0 100644 --- a/gemfiles/rails_42.gemfile +++ b/gemfiles/rails_42.gemfile @@ -15,7 +15,7 @@ gem "inherited_resources" gem "draper", "~> 2.1" group :development do - gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" gem "yard" diff --git a/gemfiles/rails_50.gemfile b/gemfiles/rails_50.gemfile index 51e416a97b9..ae478989cca 100644 --- a/gemfiles/rails_50.gemfile +++ b/gemfiles/rails_50.gemfile @@ -15,7 +15,7 @@ gem "inherited_resources", :git => "https://github.com/activeadmin/inherited_res gem "draper", "> 3.x" group :development do - gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] + gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] gem "binding_of_caller", :platforms => :mri gem "rack-mini-profiler" gem "yard" From 978c8ee33fe7d7f0f953da478e6fd49030734ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 30 Jan 2017 22:28:12 -0200 Subject: [PATCH 0279/3836] Add a couple of notes to CONTRIBUTING --- CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2fdbcb64b8a..7aa6131305b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,6 +51,13 @@ If your tests are passing locally but they're failing on Travis, reset your test rm -rf spec/rails && script/appraisal update ``` +If you find running everything through appraisal too verbose, you can also do +`export BUNDLE_GEMFILE=gemfiles/rails_50.gemfile` and then run all commands +directly (`bundle exec rake test`, `bundle exec rake setup`) without Appraisal. + +If you find issues apparently related to `bundler`, check the `.travis.yml` file +and make sure you're using exactly the same version Travis is using. + ### 4. Implement your fix or feature At this point, you're ready to make your changes! Feel free to ask for help; From f5cb0ba599db4c0cb86e47734384d6f3dc0b0e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 30 Jan 2017 22:42:10 -0200 Subject: [PATCH 0280/3836] Fix travis matrix exclusions It was using the old way of switching Rails versions (which no longer works) instead of Appraisal! --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 525271ceea5..585c852cab4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,20 +46,20 @@ matrix: gemfile: gemfiles/rails_50.gemfile - rvm: 2.4.0 - env: RAILS=3.2.22 + gemfile: gemfiles/rails_32.gemfile - rvm: 2.4.0 - env: RAILS=4.0.13 + gemfile: gemfiles/rails_40.gemfile - rvm: 2.4.0 - env: RAILS=4.1.16 + gemfile: gemfiles/rails_41.gemfile allow_failures: - rvm: jruby-9.1.7.0 gemfile: gemfiles/rails_50.gemfile - rvm: 2.4.0 - env: RAILS=4.2.7.1 + gemfile: gemfiles/rails_42.gemfile notifications: irc: From a5553c9762f686c054f81ead226ea70cfe580adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 31 Jan 2017 09:08:14 -0200 Subject: [PATCH 0281/3836] Remove dead test code --- spec/rails_helper.rb | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index f162f4c1181..afa7824460d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -37,18 +37,6 @@ def load_resources reload_routes! end - # Sets up a describe block where you can render controller - # actions. Uses the Admin::PostsController as the subject - # for the describe block - def describe_with_render(*args, &block) - describe *args do - include RSpec::Rails::ControllerExampleGroup - render_views - # metadata[:behaviour][:describes] = ActiveAdmin.namespaces[:admin].resources['Post'].controller - module_eval &block - end - end - def arbre(assigns = {}, helpers = mock_action_view, &block) Arbre::Context.new(assigns, helpers, &block) end @@ -57,15 +45,6 @@ def render_arbre_component(assigns = {}, helpers = mock_action_view, &block) arbre(assigns, helpers, &block).children.first end - # Setup a describe block which uses capybara and rails integration - # test methods. - def describe_with_capybara(*args, &block) - describe *args do - include RSpec::Rails::IntegrationExampleGroup - module_eval &block - end - end - # Returns a fake action view instance to use with our renderers def mock_action_view(assigns = {}) controller = ActionView::TestCase::TestController.new From 8dfce0a3c8b30228a69f8f17f6d08b8ed5151772 Mon Sep 17 00:00:00 2001 From: Charles Maresh Date: Mon, 10 Oct 2016 21:48:28 -0500 Subject: [PATCH 0282/3836] Include params when building IndexList link URLs - Add test to prevent regressions - Exclude page, commit, and format params from the URL - Revert https://github.com/activeadmin/activeadmin/commit/4f2916bef684c695afd6346e2365e4d0bdc25927#commitcomment-19367841 --- .../views/components/index_list.rb | 5 ++++- spec/unit/views/components/index_list_spec.rb | 20 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/active_admin/views/components/index_list.rb b/lib/active_admin/views/components/index_list.rb index 90a39042465..03c8fd40aa8 100644 --- a/lib/active_admin/views/components/index_list.rb +++ b/lib/active_admin/views/components/index_list.rb @@ -36,7 +36,10 @@ def build(index_classes) # @param [Class] index_class The class on which to build the link and html classes def build_index_list(index_class) li class: classes_for_index(index_class) do - a href: url_for(as: index_class.index_name.to_sym), class: "table_tools_button" do + params = request.query_parameters.except :page, :commit, :format + url_with_params = url_for(params.merge(as: index_class.index_name.to_sym)) + + a href: url_with_params, class: "table_tools_button" do name = index_class.index_name I18n.t("active_admin.index_list.#{name}", default: name.to_s.titleize) end diff --git a/spec/unit/views/components/index_list_spec.rb b/spec/unit/views/components/index_list_spec.rb index ec72f760336..d7e60cde142 100644 --- a/spec/unit/views/components/index_list_spec.rb +++ b/spec/unit/views/components/index_list_spec.rb @@ -4,13 +4,19 @@ describe "#index_list_renderer" do - let(:index_classes) { [ActiveAdmin::Views::IndexAsTable, ActiveAdmin::Views::IndexAsBlock] } + let(:collection) { + Post.create(title: 'First Post', starred: true) + Post.where(nil) + } + let(:helpers) do helpers = mock_action_view - allow(helpers).to receive(:url_for).and_return("/") - allow(helpers).to receive(:params).and_return as: "table" + allow(helpers).to receive(:url_for) { |url| "/?#{ url.to_query }" } + allow(helpers.request).to receive(:query_parameters).and_return as: "table", q: { title_contains: "terms" } + allow(helpers).to receive(:params).and_return as: "table", q: { title_contains: "terms" } + allow(helpers).to receive(:collection).and_return(collection) helpers end @@ -31,5 +37,13 @@ expect(a_tags.first.to_s).to include("Table") expect(a_tags.last.to_s).to include("List") end + + it "should maintain index filter parameters" do + a_tags = subject.find_by_tag("a") + expect(a_tags.first.attributes[:href]) + .to eq("/?#{ { as: "table", q: { title_contains: "terms" } }.to_query }") + expect(a_tags.last.attributes[:href]) + .to eq("/?#{ { as: "block", q: { title_contains: "terms" } }.to_query }") + end end end From 2ae3ae915d174e22f311a1ac9c3ce620468116d1 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 1 Feb 2017 21:55:38 +0200 Subject: [PATCH 0283/3836] added feature test for belongs to form --- features/belongs_to.feature | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/features/belongs_to.feature b/features/belongs_to.feature index acc4f0e9c74..547e9792c7b 100644 --- a/features/belongs_to.feature +++ b/features/belongs_to.feature @@ -21,8 +21,33 @@ Feature: Belongs To And I should see "Displaying 1 Post" And I should see a link to "Users" in the breadcrumb And I should see a link to "Jane Doe" in the breadcrumb - When I follow "Edit" - Then I should see a link to "Hello World" in the breadcrumb + + Scenario: Updating a child resource page + Given a configuration of: + """ + ActiveAdmin.register User + ActiveAdmin.register Post do + belongs_to :user + permit_params :title, :body, :published_date if Rails::VERSION::MAJOR >= 4 + + form do |f| + f.inputs "Your Post" do + f.input :title + f.input :body + end + f.inputs "Publishing" do + f.input :published_date + end + f.actions + end + end + """ + When I go to the last author's last post page + And I follow "Edit Post" + And I should see the element "form[action='/admin/users/2/posts/2']" + And I should see a link to "Hello World" in the breadcrumb + When I press "Update Post" + Then I should see "Post was successfully updated." Scenario: Viewing a child resource page Given a configuration of: From 5807f58c9471f47889f81e2e753c1d4a2fd064ff Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 1 Feb 2017 22:57:21 +0200 Subject: [PATCH 0284/3836] fixed permitted params for nested resources --- lib/active_admin/resource.rb | 4 ++++ lib/active_admin/resource/belongs_to.rb | 4 ++++ lib/active_admin/resource_dsl.rb | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/resource.rb b/lib/active_admin/resource.rb index b48abc52c37..a532c87ff2c 100644 --- a/lib/active_admin/resource.rb +++ b/lib/active_admin/resource.rb @@ -135,6 +135,10 @@ def belongs_to_config @belongs_to ||= [] end + def belongs_to_params + belongs_to_config.select{ |c| c.required? }.map{ |c| c.to_param } + end + # Do we belong to another resource? def belongs_to? belongs_to_config.length > 0 diff --git a/lib/active_admin/resource/belongs_to.rb b/lib/active_admin/resource/belongs_to.rb index 4ec21d55612..d223ef51760 100644 --- a/lib/active_admin/resource/belongs_to.rb +++ b/lib/active_admin/resource/belongs_to.rb @@ -39,6 +39,10 @@ def optional? def required? !optional? end + + def to_param + :"#{@target_name}_id" + end end end end diff --git a/lib/active_admin/resource_dsl.rb b/lib/active_admin/resource_dsl.rb index 68b0308439f..c730d6b8f93 100644 --- a/lib/active_admin/resource_dsl.rb +++ b/lib/active_admin/resource_dsl.rb @@ -68,10 +68,11 @@ def includes(*args) # def permit_params(*args, &block) param_key = config.param_key.to_sym + belongs_to_params = config.belongs_to_params controller do define_method :permitted_params do - params.permit *active_admin_namespace.permitted_params, + params.permit *(active_admin_namespace.permitted_params + belongs_to_params), param_key => block ? instance_exec(&block) : args end end From e5cb55ba4cae7ff8a821c5fc0dd86dfb690aa322 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 1 Feb 2017 23:19:34 +0200 Subject: [PATCH 0285/3836] added note to documentation about permit_params on nested resources --- docs/2-resource-customization.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index 6dc888481eb..29b643e44f9 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -65,6 +65,15 @@ ActiveAdmin.register Post do end ``` +If your resource is nested, declare `permit_params` after `belongs_to`: + +```ruby +ActiveAdmin.register Post do + belongs_to :user + permit_params :title, :content, :publisher_id +end + + The `permit_params` call creates a method called `permitted_params`. You should use this method when overriding `create` or `update` actions: ```ruby From 28891b58716ba3348d47447f085d88bbdea29c4d Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 2 Feb 2017 10:04:41 +0200 Subject: [PATCH 0286/3836] added feature test for creation of nested resources --- features/belongs_to.feature | 39 ++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/features/belongs_to.feature b/features/belongs_to.feature index 547e9792c7b..13b73e7364a 100644 --- a/features/belongs_to.feature +++ b/features/belongs_to.feature @@ -43,12 +43,45 @@ Feature: Belongs To end """ When I go to the last author's last post page - And I follow "Edit Post" - And I should see the element "form[action='/admin/users/2/posts/2']" - And I should see a link to "Hello World" in the breadcrumb + Then I follow "Edit Post" + Then I should see the element "form[action='/admin/users/2/posts/2']" + Then I should see a link to "Hello World" in the breadcrumb + When I press "Update Post" Then I should see "Post was successfully updated." + Scenario: Creating a child resource page + Given a configuration of: + """ + ActiveAdmin.register User + ActiveAdmin.register Post do + belongs_to :user + permit_params :title, :body, :published_date if Rails::VERSION::MAJOR >= 4 + + form do |f| + f.inputs "Your Post" do + f.input :title + f.input :body + end + f.inputs "Publishing" do + f.input :published_date + end + f.actions + end + end + """ + When I go to the last author's posts + Then I follow "New Post" + Then I should see the element "form[action='/admin/users/2/posts']" + Then I fill in "Title" with "Hello World" + Then I fill in "Body" with "This is the body" + + When I press "Create Post" + Then I should see "Post was successfully created." + And I should see the attribute "Title" with "Hello World" + And I should see the attribute "Body" with "This is the body" + And I should see the attribute "Author" with "Jane Doe" + Scenario: Viewing a child resource page Given a configuration of: """ From eced130d24b887337efc84bbc7192b0c3d824de6 Mon Sep 17 00:00:00 2001 From: Charles Maresh Date: Fri, 6 Dec 2013 18:27:04 -0600 Subject: [PATCH 0287/3836] Add the belongs_to functionality to Page resources --- features/registering_pages.feature | 17 ++++++++ features/support/paths.rb | 2 + lib/active_admin/page.rb | 18 +++++++-- lib/active_admin/page_dsl.rb | 4 ++ spec/unit/namespace/register_page_spec.rb | 28 ++++++++++++- spec/unit/page_spec.rb | 49 +++++++++++++++++++++++ 6 files changed, 113 insertions(+), 5 deletions(-) diff --git a/features/registering_pages.feature b/features/registering_pages.feature index 355c461c205..fb1c93ddb1c 100644 --- a/features/registering_pages.feature +++ b/features/registering_pages.feature @@ -169,3 +169,20 @@ Feature: Registering Pages Then I should see the page title "Special users" And I should see the Active Admin layout And I should see 1 user in the table + + Scenario: Displaying parent information from a belongs_to page + Given a configuration of: + """ + ActiveAdmin.register Post + ActiveAdmin.register_page "Status" do + belongs_to :post + + content do + "Status page for #{parent.title}" + end + end + """ + And 1 post with the title "Post 1" exists + When I go to the first post custom status page + Then I should see the content "Status page for Post 1" + diff --git a/features/support/paths.rb b/features/support/paths.rb index 8425987a722..aac94b43060 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -21,6 +21,8 @@ def path_to(page_name) "/admin/login" when /the first post show page/ "/admin/posts/1" + when /the first post custom status page/ + "/admin/posts/1/status" when /the first post edit page/ "/admin/posts/1/edit" when /the admin password reset form with token "([^"]*)"/ diff --git a/lib/active_admin/page.rb b/lib/active_admin/page.rb index 461e2168a90..76b31e836c8 100644 --- a/lib/active_admin/page.rb +++ b/lib/active_admin/page.rb @@ -73,10 +73,6 @@ def route_uncountable? false end - def belongs_to? - false - end - def add_default_action_items end @@ -88,5 +84,19 @@ def clear_page_actions! @page_actions = [] end + def belongs_to(target, options = {}) + @belongs_to = Resource::BelongsTo.new(self, target, options) + self.navigation_menu_name = target unless @belongs_to.optional? + controller.send :belongs_to, target, options.dup + end + + def belongs_to_config + @belongs_to + end + + # Do we belong to another resource? + def belongs_to? + !!belongs_to_config + end end end diff --git a/lib/active_admin/page_dsl.rb b/lib/active_admin/page_dsl.rb index 83ef9eed850..4a2344ed5f3 100644 --- a/lib/active_admin/page_dsl.rb +++ b/lib/active_admin/page_dsl.rb @@ -24,5 +24,9 @@ def page_action(name, options = {}, &block) define_method(name, &block || Proc.new{}) end end + + def belongs_to(target, options = {}) + config.belongs_to(target, options) + end end end diff --git a/spec/unit/namespace/register_page_spec.rb b/spec/unit/namespace/register_page_spec.rb index 5de0b6a1e80..2572037f414 100644 --- a/spec/unit/namespace/register_page_spec.rb +++ b/spec/unit/namespace/register_page_spec.rb @@ -68,6 +68,32 @@ it "should not create a menu item" do expect(menu["Status"]).to eq nil end + end # describe "disabling the menu" + end # describe "adding to the menu" + + describe "adding as a belongs to" do + context "when not optional" do + before do + namespace.register_page "Reports" do + belongs_to :author + end + end + + it "should be excluded from the menu" do + expect(menu["Reports"]).to be_nil + end end - end + + context "when optional" do + before do + namespace.register_page "Reports" do + belongs_to :author, :optional => true + end + end + + it "should be in the menu" do + expect(menu["Reports"]).to_not be_nil + end + end + end # describe "adding as a belongs to" end diff --git a/spec/unit/page_spec.rb b/spec/unit/page_spec.rb index 2f37f799e71..5e2a35a93bc 100644 --- a/spec/unit/page_spec.rb +++ b/spec/unit/page_spec.rb @@ -11,6 +11,7 @@ module ActiveAdmin let(:application){ ActiveAdmin::Application.new } let(:namespace){ Namespace.new(application, :admin) } + let(:page_name) { "Chocolate I lØve You!" } def config(options = {}) @config ||= namespace.register_page("Chocolate I lØve You!", options) @@ -70,6 +71,7 @@ def config(options = {}) expect(config.belongs_to?).to eq false end + it "should not have any action_items" do expect(config.action_items?).to eq false end @@ -78,5 +80,52 @@ def config(options = {}) expect(config.sidebar_sections?).to eq false end + context "with belongs to config" do + let!(:post_config) { namespace.register Post } + let!(:page_config) { + namespace.register_page page_name do + belongs_to :post + end + } + + it "configures page with belongs_to" do + expect(page_config.belongs_to?).to be true + end + + it "sets navigation menu to parent" do + expect(page_config.navigation_menu_name).to eq :post + end + + it "builds a belongs_to relationship" do + belongs_to = page_config.belongs_to_config + + expect(belongs_to.target).to eq(post_config) + expect(belongs_to.owner).to eq(page_config) + expect(belongs_to.optional?).to be_falsy + end + + it "forwards belongs_to call to controller" do + options = { optional: true } + expect(page_config.controller).to receive(:belongs_to).with(:post, options) + page_config.belongs_to :post, options + end + end # context "with belongs to config" do + + context "with optional belongs to config" do + let!(:post_config) { namespace.register Post } + let!(:page_config) { + namespace.register_page page_name do + belongs_to :post, optional: true + end + } + + it "does not override default navigation menu" do + expect(page_config.navigation_menu_name).to eq(:default) + end + end # context "with optional belongs to config" do + + it "has no belongs_to by default" do + expect(config.belongs_to?).to be_falsy + end end end From 05877d45d464d1911ca7d53072c81516c7614281 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 25 Jan 2017 21:09:26 +0200 Subject: [PATCH 0288/3836] belongs_to convension for page fixed to use same logic as resource --- features/registering_pages.feature | 3 ++- lib/active_admin/page.rb | 13 +++++++++---- spec/unit/page_spec.rb | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/features/registering_pages.feature b/features/registering_pages.feature index fb1c93ddb1c..0756efc6993 100644 --- a/features/registering_pages.feature +++ b/features/registering_pages.feature @@ -178,11 +178,12 @@ Feature: Registering Pages belongs_to :post content do - "Status page for #{parent.title}" + "Status page for #{helpers.parent.title}" end end """ And 1 post with the title "Post 1" exists When I go to the first post custom status page Then I should see the content "Status page for Post 1" + And I should see a link to "Post 1" in the breadcrumb diff --git a/lib/active_admin/page.rb b/lib/active_admin/page.rb index 76b31e836c8..e448e180221 100644 --- a/lib/active_admin/page.rb +++ b/lib/active_admin/page.rb @@ -85,18 +85,23 @@ def clear_page_actions! end def belongs_to(target, options = {}) - @belongs_to = Resource::BelongsTo.new(self, target, options) - self.navigation_menu_name = target unless @belongs_to.optional? + this_belongs_to = Resource::BelongsTo.new(self, target, options) + belongs_to_config << this_belongs_to + self.navigation_menu_name = target unless this_belongs_to.optional? controller.send :belongs_to, target, options.dup end def belongs_to_config - @belongs_to + @belongs_to ||= [] end # Do we belong to another resource? def belongs_to? - !!belongs_to_config + belongs_to_config.length > 0 + end + + def breadcrumb + instance_variable_defined?(:@breadcrumb) ? @breadcrumb : namespace.breadcrumb end end end diff --git a/spec/unit/page_spec.rb b/spec/unit/page_spec.rb index 5e2a35a93bc..0ff3cbf5b64 100644 --- a/spec/unit/page_spec.rb +++ b/spec/unit/page_spec.rb @@ -97,7 +97,7 @@ def config(options = {}) end it "builds a belongs_to relationship" do - belongs_to = page_config.belongs_to_config + belongs_to = page_config.belongs_to_config.first expect(belongs_to.target).to eq(post_config) expect(belongs_to.owner).to eq(page_config) From 9107ba1496c0d7c70427f71bcf2ad13cde24c4bc Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Fri, 3 Feb 2017 10:15:10 +0200 Subject: [PATCH 0289/3836] added docs and changelog about using belogs_to in pages --- CHANGELOG.md | 4 ++++ docs/10-custom-pages.md | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4a3c6084bd..55a6ed6396e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ #### Minor +* Page supports belongs_to [#4759][] by [@Fivell][] and [@zorab47][] * Support for custom sorting strategies [#4768][] by [@Fivell][] * Stream CSV downloads as they're generated [#3038][] by [@craigmcnamara][] * Disable streaming in development for easier debugging [#3535][] by [@seanlinsley][] @@ -105,6 +106,8 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [#3731]: https://github.com/activeadmin/activeadmin/issues/3731 [#3783]: https://github.com/activeadmin/activeadmin/issues/3783 [#4187]: https://github.com/activeadmin/activeadmin/issues/4187 +[#4759]: https://github.com/activeadmin/activeadmin/pull/4759 +[#4768]: https://github.com/activeadmin/activeadmin/pull/4768 [@PChambino]: https://github.com/PChambino [@TimPetricola]: https://github.com/TimPetricola [@chancancode]: https://github.com/chancancode @@ -120,3 +123,4 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [@timoschilling]: https://github.com/timoschilling [@varyonic]: https://github.com/varyonic [@zorab47]: https://github.com/zorab47 +[@Fivell]: https://github.com/Fivell \ No newline at end of file diff --git a/docs/10-custom-pages.md b/docs/10-custom-pages.md index 12332c63532..2d288b1d6d9 100644 --- a/docs/10-custom-pages.md +++ b/docs/10-custom-pages.md @@ -71,6 +71,19 @@ ActiveAdmin.register_page "Calendar", namespace: :today ActiveAdmin.register_page "Calendar", namespace: false ``` +## Belongs To + +To nest the page within another resource, you can use the `belongs_to` method: + +```ruby +ActiveAdmin.register Project +ActiveAdmin.register_page "Status" do + belongs_to :project +end +``` + +See also the [Belongs To](2-resource-customization.md#belongs-to) documentation and examples. + ## Add a Sidebar See the [Sidebars](7-sidebars.md) documentation. From dee31817a7c5a2088af5baa944b377aeb4f8f762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 4 Feb 2017 19:57:26 -0200 Subject: [PATCH 0290/3836] Add a couple of extra contributing notes --- CONTRIBUTING.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7aa6131305b..1d94f6e572b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,6 +26,16 @@ git checkout -b 325-add-japanese-translations ### 3. Get the test suite running +Make sure you're using a recent ruby and have the `bundler` gem installed, at +least version `1.14.3`. The most reliable `bundler` version to use is the same +Travis is using. + +Install `appraisal` and the other common development dependencies: + +```sh +bundle install +``` + Install the development dependencies: ```sh @@ -55,9 +65,6 @@ If you find running everything through appraisal too verbose, you can also do `export BUNDLE_GEMFILE=gemfiles/rails_50.gemfile` and then run all commands directly (`bundle exec rake test`, `bundle exec rake setup`) without Appraisal. -If you find issues apparently related to `bundler`, check the `.travis.yml` file -and make sure you're using exactly the same version Travis is using. - ### 4. Implement your fix or feature At this point, you're ready to make your changes! Feel free to ask for help; From 4df0cb69e8a6ac270f97470160f2daec28d0a66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 31 Jan 2017 19:30:00 -0200 Subject: [PATCH 0291/3836] Further simplify appraisal setup * To run the tests, `bundle exec rake`. * To run the sample app, `bundle exec local server`. --- .gitignore | 2 +- CONTRIBUTING.md | 44 ++++++++++++++++++++++------------------- Rakefile | 42 +++++++++++++++++++++++++++++++++++++++ script/appraisal | 17 ---------------- script/local | 51 ------------------------------------------------ tasks/local.rake | 25 ++++++++++++++++++++++++ tasks/test.rake | 25 +++++------------------- 7 files changed, 97 insertions(+), 109 deletions(-) delete mode 100755 script/appraisal delete mode 100755 script/local create mode 100644 tasks/local.rake diff --git a/.gitignore b/.gitignore index 1652eac86b6..5db25880808 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,7 @@ Gemfile.lock gemfiles/rails_[3-5][0-9].gemfile.lock capybara* viewcumber -test-rails* +.test-rails-apps public .rspec .rails-version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d94f6e572b..e316c0b0341 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,31 +39,37 @@ bundle install Install the development dependencies: ```sh -script/appraisal install +bundle exec appraisal install ``` Now you should be able to run the entire suite using: ```sh -script/appraisal rails_50 rake test +bundle exec rake test ``` -NOTE: You can also use `rails_42` or the other Rails versions defined in the -`Appraisals` file, but initial focus on the latest supported Rails version is -preferred. +This will automatically run the tests against Rails 5.0. But you can easily run +tests against older versions of Rails too. -The previous command will generate a rails application in `spec/rails` to run -the tests against. +For example, to run tests against Rails 4.2, do: + +```sh +bundle exec appraisal rails_42 rake test +``` + +The test run will generate a sample rails application in `spec/rails` to run the +tests against. If your tests are passing locally but they're failing on Travis, reset your test environment: ```sh -rm -rf spec/rails && script/appraisal update +rm -rf spec/rails && bundle exec appraisal update ``` -If you find running everything through appraisal too verbose, you can also do -`export BUNDLE_GEMFILE=gemfiles/rails_50.gemfile` and then run all commands -directly (`bundle exec rake test`, `bundle exec rake setup`) without Appraisal. +If you want to stick with a specific older Rails version for a while, you can +also do `export BUNDLE_GEMFILE=gemfiles/rails_42.gemfile` and then run all +commands directly (`bundle exec rake test`, `bundle exec rake setup`) without +Appraisal. ### 4. Implement your fix or feature @@ -78,30 +84,28 @@ a look at your changes in a browser. To boot up a test Rails app: ```sh -script/appraisal rails_50 script/local server +bundle exec rake local server ``` This will automatically create a Rails app if none already exists, and store it in the -`.test-rails-apps` folder. The currently active app is symlinked to `test-rails-app`. +`.test-rails-apps` folder. You should now be able to open in your browser. You can log in using: User: admin@example.com Password: password -If you need to perform any other commands on the test application, use the -`local` script. For example: - -To boot the rails console: +If you need to perform any other commands on the test application, just pass +them to the `local` rake task. For example, to boot the rails console: ```sh -script/appraisal rails_50 script/local console +bundle exec rake local console ``` Or to migrate the database: ```sh -script/appraisal rails_50 script/local rake db:migrate +bundle exec rake local db:migrate ``` ### 6. Run tests against major supported rails versions @@ -110,7 +114,7 @@ Once you've implemented your code, got the tests passing, previewed it in a browser, you're ready to test it against multiple versions of Rails. ```sh -script/appraisal rake test +bundle exec appraisal rake test ``` This runs our test suite against a couple of major versions of Rails. diff --git a/Rakefile b/Rakefile index 1c69f329e70..149b25f0fa9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,47 @@ require 'bundler/gem_tasks' +task :enforce_version do + if ENV['BUNDLE_GEMFILE'] == File.expand_path('../Gemfile', __FILE__) + gemfile_path = File.expand_path('../gemfiles/rails_50.gemfile', __FILE__) + + command = ['bundle', 'exec', 'rake', *ARGV].join(' ') + env = { 'BUNDLE_GEMFILE' => gemfile_path } + + Bundler.with_clean_env { Kernel.exec(env, command) } + end +end + +desc 'Creates a test rails app for the specs to run against' +task :setup, [:parallel, :dir, :template] => [:enforce_version] do |_t, opts| + require 'rails/version' + + base_dir = opts[:dir] || 'spec/rails' + app_dir = "#{base_dir}/rails-#{Rails::VERSION::STRING}" + template = opts[:template] || 'rails_template' + + if File.exist? app_dir + puts "test app #{app_dir} already exists; skipping" + else + system "mkdir -p #{base_dir}" + args = %W( + -m spec/support/#{template}.rb + --skip-bundle + --skip-listen + --skip-turbolinks + --skip-test-unit + ) + + command = ['bundle', 'exec', 'rails', 'new', app_dir, *args].join(' ') + + env = { 'BUNDLE_GEMFILE' => ENV['BUNDLE_GEMFILE'] } + env['INSTALL_PARALLEL'] = 'yes' if opts[:parallel] + + Bundler.with_clean_env { Kernel.exec(env, command) } + + Rake::Task['parallel:after_setup_hook'].invoke if opts[:parallel] + end +end + # Import all our rake tasks FileList['tasks/**/*.rake'].each { |task| import task } diff --git a/script/appraisal b/script/appraisal deleted file mode 100755 index eac3249f71f..00000000000 --- a/script/appraisal +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'appraisal' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("appraisal", "appraisal") diff --git a/script/local b/script/local deleted file mode 100755 index 5a2edbeaefa..00000000000 --- a/script/local +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env ruby - -require 'shellwords' - -unless ARGV[0] - puts <<-EOF -Usage: #{__FILE__} COMMAND [ARGS] - -The command will be run in the context of the local rails -app stored in test-rails-app. - -Examples: - -#{__FILE__} server -#{__FILE__} c -#{__FILE__} rake db:migrate - EOF - exit(1) -end - -require 'rails' - -# Set up some variables -dir = ".test-rails-apps" -path = "#{dir}/test-rails-app-#{Rails.version}" - -# Ensure .test-rails-apps is created -system "mkdir #{dir}" unless File.exist?(dir) - -# Create the sample rails app if it doesn't already exist -unless File.exist? path - args = %w[ - -m spec/support/rails_template_with_data.rb - --skip-bundle - --skip-listen - --skip-turbolinks - --skip-test-unit - ] - system "rails new #{Shellwords.escape path} #{args.join ' '}" -end - -# Link this rails app -system "rm test-rails-app" -system "ln -s #{Shellwords.escape path} test-rails-app" - -# If it's a rails command, auto add the rails script -RAILS_COMMANDS = %w{generate console server dbconsole g c s runner} -args = RAILS_COMMANDS.include?(ARGV[0]) ? ["rails", ARGV].flatten : ARGV - -# Run the command -exec "cd test-rails-app && #{args.join(" ")}" diff --git a/tasks/local.rake b/tasks/local.rake new file mode 100644 index 00000000000..521453fb885 --- /dev/null +++ b/tasks/local.rake @@ -0,0 +1,25 @@ +desc 'Runs a command agains the local sample application' +task local: :enforce_version do + Rake::Task['setup'].invoke(false, + '.test-rails-apps', + 'rails_template_with_data') + + app_folder = ".test-rails-apps/rails-#{Rails::VERSION::STRING}" + + # Discard the "local" argument (name of the task) + argv = ARGV[1..-1] + + # If it's a rails command, or we're using Rails 5, auto add the rails script + rails_commands = %w(generate console server dbconsole g c s runner) + + if Rails::VERSION::MAJOR >= 5 || rails_commands.include?(argv[0]) + argv.unshift('rails') + end + + command = ['bundle', 'exec', *argv].join(' ') + env = { 'BUNDLE_GEMFILE' => ENV['BUNDLE_GEMFILE'] } + + Dir.chdir(app_folder) do + Bundler.with_clean_env { Kernel.exec(env, command) } + end +end diff --git a/tasks/test.rake b/tasks/test.rake index 9fed5b6af1b..6a79f09383d 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,24 +1,9 @@ -desc "Creates a test rails app for the specs to run against" -task :setup, :parallel do |t, opts| - require 'rails/version' - if File.exist? dir = "spec/rails/rails-#{Rails::VERSION::STRING}" - puts "test app #{dir} already exists; skipping" - else - system 'mkdir -p spec/rails' - args = %w[ - -m spec/support/rails_template.rb - --skip-bundle - --skip-listen - --skip-turbolinks - --skip-test-unit - ] - system "#{'INSTALL_PARALLEL=yes' if opts[:parallel]} rails new #{dir} #{args.join ' '}" - Rake::Task['parallel:after_setup_hook'].invoke if opts[:parallel] - end -end - desc "Run the full suite using 1 core" -task test: ['spec:unit', 'spec:request', 'cucumber', 'cucumber:class_reloading'] +task test: [:enforce_version, + 'spec:unit', + 'spec:request', + 'cucumber', + 'cucumber:class_reloading'] require 'rspec/core/rake_task' From d7ac58d8040712ae97b75440156b01d0714fd1e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 7 Feb 2017 09:33:01 -0200 Subject: [PATCH 0292/3836] Add docs about running specific tests --- CONTRIBUTING.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e316c0b0341..97b0e3f0566 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,12 +51,18 @@ bundle exec rake test This will automatically run the tests against Rails 5.0. But you can easily run tests against older versions of Rails too. -For example, to run tests against Rails 4.2, do: +For example, you can run all tests against Rails 4.2: ```sh bundle exec appraisal rails_42 rake test ``` +or even just run specific tests. For example: + +```sh +bundle exec appraisal rails_42 rspec spec/unit/belongs_to_spec.rb +``` + The test run will generate a sample rails application in `spec/rails` to run the tests against. From a31a3206e3ef92cec127c09b7032d99d884c4e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 7 Feb 2017 09:33:42 -0200 Subject: [PATCH 0293/3836] Linting pass over CONTRIBUTING.md Wrap long lines, remove trailing whitespaces, no hard tabs. --- CONTRIBUTING.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 97b0e3f0566..ddf7d45a9b5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -66,7 +66,8 @@ bundle exec appraisal rails_42 rspec spec/unit/belongs_to_spec.rb The test run will generate a sample rails application in `spec/rails` to run the tests against. -If your tests are passing locally but they're failing on Travis, reset your test environment: +If your tests are passing locally but they're failing on Travis, reset your test +environment: ```sh rm -rf spec/rails && bundle exec appraisal update @@ -93,13 +94,16 @@ To boot up a test Rails app: bundle exec rake local server ``` -This will automatically create a Rails app if none already exists, and store it in the -`.test-rails-apps` folder. +This will automatically create a Rails app if none already exists, and store it +in the `.test-rails-apps` folder. -You should now be able to open in your browser. You can log in using: +You should now be able to open in your browser. +You can log in using: - User: admin@example.com - Password: password +``` +User: admin@example.com +Password: password +``` If you need to perform any other commands on the test application, just pass them to the `local` rake task. For example, to boot the rails console: @@ -146,7 +150,9 @@ git rebase master git push --set-upstream origin 325-add-japanese-translations ``` -Finally, go to GitHub and [make a Pull Request](https://help.github.com/articles/creating-a-pull-request) :D +Finally, go to GitHub and +[make a Pull Request](https://help.github.com/articles/creating-a-pull-request) +:D ### 8. Keeping your Pull Request updated From 2f0f2ad9bd1d7e7bb6079e3df03e3b5e9b5db68b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 7 Feb 2017 09:34:32 -0200 Subject: [PATCH 0294/3836] Remove a rule nobody follows --- CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ddf7d45a9b5..5ccd309771a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -179,7 +179,6 @@ A PR can only be merged into master by a maintainer if: opened the PR, only one extra approval is needed. * It has no requested changes. * It is up to date with current master. -* It has been opened for at least 48h. Any maintainer is allowed to merge a PR if all of these conditions are met. From c12736bd60732689a32ec8e35997d63d00d3c74d Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 9 Feb 2017 09:07:47 +0100 Subject: [PATCH 0295/3836] Delete install_phantomjs.sh --- script/install_phantomjs.sh | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 script/install_phantomjs.sh diff --git a/script/install_phantomjs.sh b/script/install_phantomjs.sh deleted file mode 100644 index 8a4d442e120..00000000000 --- a/script/install_phantomjs.sh +++ /dev/null @@ -1,10 +0,0 @@ -VERSION=2.1.1 -BASENAME=phantomjs-$VERSION-linux-x86_64 -FULLNAME=$BASENAME.tar.bz2 -DOWNLOAD_BASE_URI=https://github.com/Medium/phantomjs -DOWNLOAD_URI=$DOWNLOAD_BASE_URI/releases/download/v$VERSION/$FULLNAME - -export PATH=$PWD/.phantomjs/$BASENAME/bin:$PATH -mkdir -p .phantomjs -wget --quiet $DOWNLOAD_URI -O .phantomjs/$FULLNAME -tar -xvf .phantomjs/$FULLNAME -C .phantomjs $BASENAME/bin/phantomjs From 88bbc3d1b0ffd412441861c4c8d6bf4053da302e Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Thu, 9 Feb 2017 09:08:41 +0100 Subject: [PATCH 0296/3836] usa an oneliner to install phantomjs on travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 585c852cab4..1db7692d456 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ bundler_args: --without development cache: bundler before_install: - - source script/install_phantomjs.sh + - export PATH=$(npm bin):$PATH && if [ $(phantomjs --version) != '2.1.1' ]; then npm install phantomjs-prebuilt; fi - gem update --system # use the very latest Rubygems - rvm @global do gem uninstall bundler -a -x - rvm @global do gem install bundler -v 1.14.3 # latest version known to work From 9a1c02b40cc9988f7873d5b60a2904ddde8b8c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 10 Feb 2017 09:24:49 -0200 Subject: [PATCH 0297/3836] Try to get Rails 4.2 + Ruby 2.4.0 tests passing --- .travis.yml | 3 --- Appraisals | 2 +- gemfiles/rails_42.gemfile | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 585c852cab4..2c37f5545ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,9 +58,6 @@ matrix: - rvm: jruby-9.1.7.0 gemfile: gemfiles/rails_50.gemfile - - rvm: 2.4.0 - gemfile: gemfiles/rails_42.gemfile - notifications: irc: channels: diff --git a/Appraisals b/Appraisals index 24c0f190b3e..e6272ffd3d4 100644 --- a/Appraisals +++ b/Appraisals @@ -60,7 +60,7 @@ end appraise 'rails_42' do gemspec - gem 'rails', '4.2.7.1' + gem 'rails', '4.2.8.rc1' gem 'jquery-ui-rails', '~> 5.0' gem 'devise', '~> 3.5' diff --git a/gemfiles/rails_42.gemfile b/gemfiles/rails_42.gemfile index 7169b773fe0..0200b47b190 100644 --- a/gemfiles/rails_42.gemfile +++ b/gemfiles/rails_42.gemfile @@ -8,7 +8,7 @@ gem "thor", "<= 0.19.1" gem "rake" gem "parallel_tests", "< 2.10" gem "pry" -gem "rails", "4.2.7.1" +gem "rails", "4.2.8.rc1" gem "jquery-ui-rails", "~> 5.0" gem "devise", "~> 3.5" gem "inherited_resources" From ef5a6b6c6e8f685d4c57d04ba8100e924bd2607a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 10 Feb 2017 09:59:36 -0200 Subject: [PATCH 0298/3836] Try to get jruby + Rails 5 tests passing --- .travis.yml | 4 ---- Appraisals | 13 +++++++++++++ Gemfile | 1 - gemfiles/rails_32.gemfile | 2 +- gemfiles/rails_40.gemfile | 2 +- gemfiles/rails_41.gemfile | 2 +- gemfiles/rails_42.gemfile | 2 +- gemfiles/rails_50.gemfile | 2 +- 8 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c37f5545ce..a804f94ba8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,10 +54,6 @@ matrix: - rvm: 2.4.0 gemfile: gemfiles/rails_41.gemfile - allow_failures: - - rvm: jruby-9.1.7.0 - gemfile: gemfiles/rails_50.gemfile - notifications: irc: channels: diff --git a/Appraisals b/Appraisals index e6272ffd3d4..0b097950276 100644 --- a/Appraisals +++ b/Appraisals @@ -17,6 +17,8 @@ appraise 'rails_32' do gem 'nokogiri', '< 1.7' gem 'public_suffix', '< 1.5' end + + gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby end appraise 'rails_40' do @@ -36,6 +38,8 @@ appraise 'rails_40' do gem 'nokogiri', '< 1.7' gem 'public_suffix', '< 1.5' end + + gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby end appraise 'rails_41' do @@ -55,6 +59,8 @@ appraise 'rails_41' do gem 'nokogiri', '< 1.7' gem 'public_suffix', '< 1.5' end + + gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby end appraise 'rails_42' do @@ -74,6 +80,8 @@ appraise 'rails_42' do gem 'nokogiri', '< 1.7' gem 'public_suffix', '< 1.5' end + + gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby end appraise 'rails_50' do @@ -87,4 +95,9 @@ appraise 'rails_50' do gem 'inherited_resources', git: 'https://github.com/activeadmin/inherited_resources' gem 'draper', '> 3.x' + + gem 'activerecord-jdbcsqlite3-adapter', + git: 'https://github.com/jruby/activerecord-jdbc-adapter', + branch: 'rails-5', + platforms: :jruby end diff --git a/Gemfile b/Gemfile index cf4177e8469..c490fb04a7a 100644 --- a/Gemfile +++ b/Gemfile @@ -46,6 +46,5 @@ group :test do gem 'i18n-spec' gem 'shoulda-matchers', '<= 2.8.0' gem 'sqlite3', platforms: :mri - gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby gem 'poltergeist' end diff --git a/gemfiles/rails_32.gemfile b/gemfiles/rails_32.gemfile index 046a26e39ed..ff5f536c348 100644 --- a/gemfiles/rails_32.gemfile +++ b/gemfiles/rails_32.gemfile @@ -14,6 +14,7 @@ gem "devise", "~> 3.5" gem "inherited_resources" gem "test-unit", "~> 3.0" gem "draper", "~> 2.1" +gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] @@ -40,7 +41,6 @@ group :test do gem "i18n-spec" gem "shoulda-matchers", "<= 2.8.0" gem "sqlite3", :platforms => :mri - gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "poltergeist" end diff --git a/gemfiles/rails_40.gemfile b/gemfiles/rails_40.gemfile index 0326df20979..e076be3e061 100644 --- a/gemfiles/rails_40.gemfile +++ b/gemfiles/rails_40.gemfile @@ -13,6 +13,7 @@ gem "jquery-ui-rails", "~> 5.0" gem "devise", "~> 3.5" gem "inherited_resources" gem "draper", "~> 2.1" +gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] @@ -39,7 +40,6 @@ group :test do gem "i18n-spec" gem "shoulda-matchers", "<= 2.8.0" gem "sqlite3", :platforms => :mri - gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "poltergeist" end diff --git a/gemfiles/rails_41.gemfile b/gemfiles/rails_41.gemfile index acb75943718..c01c58ebace 100644 --- a/gemfiles/rails_41.gemfile +++ b/gemfiles/rails_41.gemfile @@ -13,6 +13,7 @@ gem "jquery-ui-rails", "~> 5.0" gem "devise", "~> 3.5" gem "inherited_resources" gem "draper", "~> 2.1" +gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] @@ -39,7 +40,6 @@ group :test do gem "i18n-spec" gem "shoulda-matchers", "<= 2.8.0" gem "sqlite3", :platforms => :mri - gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "poltergeist" end diff --git a/gemfiles/rails_42.gemfile b/gemfiles/rails_42.gemfile index 0200b47b190..5020414bea8 100644 --- a/gemfiles/rails_42.gemfile +++ b/gemfiles/rails_42.gemfile @@ -13,6 +13,7 @@ gem "jquery-ui-rails", "~> 5.0" gem "devise", "~> 3.5" gem "inherited_resources" gem "draper", "~> 2.1" +gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] @@ -39,7 +40,6 @@ group :test do gem "i18n-spec" gem "shoulda-matchers", "<= 2.8.0" gem "sqlite3", :platforms => :mri - gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "poltergeist" end diff --git a/gemfiles/rails_50.gemfile b/gemfiles/rails_50.gemfile index ae478989cca..99d399eef28 100644 --- a/gemfiles/rails_50.gemfile +++ b/gemfiles/rails_50.gemfile @@ -13,6 +13,7 @@ gem "jquery-ui-rails", "~> 5.0" gem "devise", "> 4.x" gem "inherited_resources", :git => "https://github.com/activeadmin/inherited_resources" gem "draper", "> 3.x" +gem "activerecord-jdbcsqlite3-adapter", :git => "https://github.com/jruby/activerecord-jdbc-adapter", :branch => "rails-5", :platforms => :jruby group :development do gem "better_errors", :platforms => [:ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24] @@ -39,7 +40,6 @@ group :test do gem "i18n-spec" gem "shoulda-matchers", "<= 2.8.0" gem "sqlite3", :platforms => :mri - gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "poltergeist" end From d2bfb3971b33e682441c564709787653508656c6 Mon Sep 17 00:00:00 2001 From: Chuck Callebs Date: Thu, 9 Feb 2017 08:40:55 -0500 Subject: [PATCH 0299/3836] Add Rails 5 bug report template. --- lib/bug_report_templates/rails_5.rb | 148 ++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 lib/bug_report_templates/rails_5.rb diff --git a/lib/bug_report_templates/rails_5.rb b/lib/bug_report_templates/rails_5.rb new file mode 100644 index 00000000000..63be7c76e42 --- /dev/null +++ b/lib/bug_report_templates/rails_5.rb @@ -0,0 +1,148 @@ +begin + require 'bundler/inline' +rescue LoadError => e + $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler' + raise e +end + +gemfile(true) do + source 'https://rubygems.org' + + gem 'rails' + gem 'arel' + gem 'sqlite3' + gem 'activeadmin', git: 'https://github.com/activeadmin/activeadmin', require: false + gem 'arbre', '~> 1.0', '>= 1.0.2', require: false + gem 'bourbon' + gem 'coffee-rails' + gem 'formtastic', '~> 3.1' + gem 'formtastic_i18n' + gem 'inherited_resources', '~> 1.7', git: 'https://github.com/activeadmin/inherited_resources', require: false + gem 'jquery-rails' + gem 'jquery-ui-rails' + gem 'kaminari', '>= 0.15', '< 2.0' + gem 'railties', '>= 3.2', '< 5.1' + gem 'ransack', '1.3' + gem 'sass-rails' + gem 'sprockets', '< 4.1' +end + +require 'rails' +require 'active_record' +require 'action_controller' +require 'inherited_resources' +require 'logger' + +ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') +ActiveRecord::Base.logger = Logger.new(STDOUT) + +ActiveRecord::Schema.define do + create_table :active_admin_comments, force: true do |t| + end + + # Add your schema here + create_table :your_model, force: true do |t| + end +end + + +class ApplicationController < ActionController::Base; end; + +# Trying to figure out how to include this automatically +module InheritedResources + # = Base + # + # This is the base class that holds all actions. If you see the code for each + # action, they are quite similar to Rails default scaffold. + # + # To change your base behavior, you can overwrite your actions and call super, + # call default class method, call <actions class method + # or overwrite some helpers in the base_helpers.rb file. + # + class Base < ::ApplicationController + # Overwrite inherit_resources to add specific InheritedResources behavior. + def self.inherit_resources(base) + base.class_eval do + include InheritedResources::Actions + include InheritedResources::BaseHelpers + extend InheritedResources::ClassMethods + extend InheritedResources::UrlHelpers + + # Add at least :html mime type + respond_to :html if self.mimes_for_respond_to.empty? + self.responder = InheritedResources::Responder + + helper_method :resource, :collection, :resource_class, :association_chain, + :resource_instance_name, :resource_collection_name, + :resource_url, :resource_path, + :collection_url, :collection_path, + :new_resource_url, :new_resource_path, + :edit_resource_url, :edit_resource_path, + :parent_url, :parent_path, + :smart_resource_url, :smart_collection_url + + self.class_attribute :resource_class, :instance_writer => false unless self.respond_to? :resource_class + self.class_attribute :parents_symbols, :resources_configuration, :instance_writer => false + + protected :resource_class, :parents_symbols, :resources_configuration, + :resource_class?, :parents_symbols?, :resources_configuration? + end + end + + inherit_resources(self) + end +end + +require 'activeadmin' + +class TestApp < Rails::Application + config.root = File.dirname(__FILE__) + config.logger = Logger.new($stdout) + Rails.logger = config.logger + + secrets.secret_token = 'secret_token' + secrets.secret_key_base = 'secret_key_base' + + # Define any models required to duplicate your issue + class YourModel < ActiveRecord::Base; end; + + # Define any ActiveAdmin configuration necessary to duplicate your issue + ActiveAdmin.setup do |config| + # Authentication disabled by default. Override if necessary + config.authentication_method = false + config.current_user_method = false + end + + ActiveAdmin.register_page 'Dashboard' do + content do + 'Test Me' + end + end + + # Set up your models as you have them in your ActiveAdmin config + ActiveAdmin.register YourModel do + end + + routes.draw do + ActiveAdmin.routes(self) + end +end + +require 'minitest/autorun' +require 'rack/test' + +# Replace this with the code necessary to make your test fail. +class BugTest < Minitest::Test + include Rack::Test::Methods + + def test_returns_success? + get '/admin' + assert last_response.ok? + end + + private + + def app + Rails.application + end +end From 15e240586feff398d4f02d6ad4395cfcdfccbc7a Mon Sep 17 00:00:00 2001 From: Denis Talakevich Date: Sun, 12 Feb 2017 11:27:09 +0200 Subject: [PATCH 0300/3836] add bug report template for rails 5 master add info to CONTRIBUTING.md add integration with rspec tests --- CONTRIBUTING.md | 25 +++- lib/bug_report_templates/rails_5.rb | 148 --------------------- lib/bug_report_templates/rails_5_master.rb | 120 +++++++++++++++++ spec/bug_report_templates_spec.rb | 24 ++++ 4 files changed, 163 insertions(+), 154 deletions(-) delete mode 100644 lib/bug_report_templates/rails_5.rb create mode 100644 lib/bug_report_templates/rails_5_master.rb create mode 100644 spec/bug_report_templates_spec.rb diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5ccd309771a..578d6e7de5e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,12 +78,25 @@ also do `export BUNDLE_GEMFILE=gemfiles/rails_42.gemfile` and then run all commands directly (`bundle exec rake test`, `bundle exec rake setup`) without Appraisal. -### 4. Implement your fix or feature +#### 4. Did you find a bug? + +* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/activeadmin/activeadmin/issues). + +* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/activeadmin/activeadmin/issues/new). +Be sure to include a **title and clear description**, as much relevant information as possible, +and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. + +* If possible, use the relevant bug report templates to create the issue. +Simply copy the content of the appropriate template into a .rb file, make the necessary changes to demonstrate the issue, +and **paste the content into the issue description**: + * [**Rails 5** issues](https://github.com/activeadmin/activeadmin/blob/master/lib/bug_report_templates/rails_5_master.rb) + +### 5. Implement your fix or feature At this point, you're ready to make your changes! Feel free to ask for help; everyone is a beginner at first :smile_cat: -### 5. View your changes in a Rails application +### 6. View your changes in a Rails application Active Admin is meant to be used by humans, not cucumbers. So make sure to take a look at your changes in a browser. @@ -118,7 +131,7 @@ Or to migrate the database: bundle exec rake local db:migrate ``` -### 6. Run tests against major supported rails versions +### 7. Run tests against major supported rails versions Once you've implemented your code, got the tests passing, previewed it in a browser, you're ready to test it against multiple versions of Rails. @@ -131,7 +144,7 @@ This runs our test suite against a couple of major versions of Rails. Travis does essentially the same thing when you open a Pull Request. We care about quality, so your PR won't be merged until all tests pass. -### 7. Make a Pull Request +### 8. Make a Pull Request At this point, you should switch back to your master branch and make sure it's up to date with Active Admin's master branch: @@ -154,7 +167,7 @@ Finally, go to GitHub and [make a Pull Request](https://help.github.com/articles/creating-a-pull-request) :D -### 8. Keeping your Pull Request updated +### 9. Keeping your Pull Request updated If a maintainer asks you to "rebase" your PR, they're saying that a lot of code has changed, and that you need to update your branch so it's easier to merge. @@ -170,7 +183,7 @@ git pull --rebase upstream master git push --force-with-lease 325-add-japanese-translations ``` -### 9. Merging a PR (maintainers only) +### 10. Merging a PR (maintainers only) A PR can only be merged into master by a maintainer if: diff --git a/lib/bug_report_templates/rails_5.rb b/lib/bug_report_templates/rails_5.rb deleted file mode 100644 index 63be7c76e42..00000000000 --- a/lib/bug_report_templates/rails_5.rb +++ /dev/null @@ -1,148 +0,0 @@ -begin - require 'bundler/inline' -rescue LoadError => e - $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler' - raise e -end - -gemfile(true) do - source 'https://rubygems.org' - - gem 'rails' - gem 'arel' - gem 'sqlite3' - gem 'activeadmin', git: 'https://github.com/activeadmin/activeadmin', require: false - gem 'arbre', '~> 1.0', '>= 1.0.2', require: false - gem 'bourbon' - gem 'coffee-rails' - gem 'formtastic', '~> 3.1' - gem 'formtastic_i18n' - gem 'inherited_resources', '~> 1.7', git: 'https://github.com/activeadmin/inherited_resources', require: false - gem 'jquery-rails' - gem 'jquery-ui-rails' - gem 'kaminari', '>= 0.15', '< 2.0' - gem 'railties', '>= 3.2', '< 5.1' - gem 'ransack', '1.3' - gem 'sass-rails' - gem 'sprockets', '< 4.1' -end - -require 'rails' -require 'active_record' -require 'action_controller' -require 'inherited_resources' -require 'logger' - -ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') -ActiveRecord::Base.logger = Logger.new(STDOUT) - -ActiveRecord::Schema.define do - create_table :active_admin_comments, force: true do |t| - end - - # Add your schema here - create_table :your_model, force: true do |t| - end -end - - -class ApplicationController < ActionController::Base; end; - -# Trying to figure out how to include this automatically -module InheritedResources - # = Base - # - # This is the base class that holds all actions. If you see the code for each - # action, they are quite similar to Rails default scaffold. - # - # To change your base behavior, you can overwrite your actions and call super, - # call default class method, call <actions class method - # or overwrite some helpers in the base_helpers.rb file. - # - class Base < ::ApplicationController - # Overwrite inherit_resources to add specific InheritedResources behavior. - def self.inherit_resources(base) - base.class_eval do - include InheritedResources::Actions - include InheritedResources::BaseHelpers - extend InheritedResources::ClassMethods - extend InheritedResources::UrlHelpers - - # Add at least :html mime type - respond_to :html if self.mimes_for_respond_to.empty? - self.responder = InheritedResources::Responder - - helper_method :resource, :collection, :resource_class, :association_chain, - :resource_instance_name, :resource_collection_name, - :resource_url, :resource_path, - :collection_url, :collection_path, - :new_resource_url, :new_resource_path, - :edit_resource_url, :edit_resource_path, - :parent_url, :parent_path, - :smart_resource_url, :smart_collection_url - - self.class_attribute :resource_class, :instance_writer => false unless self.respond_to? :resource_class - self.class_attribute :parents_symbols, :resources_configuration, :instance_writer => false - - protected :resource_class, :parents_symbols, :resources_configuration, - :resource_class?, :parents_symbols?, :resources_configuration? - end - end - - inherit_resources(self) - end -end - -require 'activeadmin' - -class TestApp < Rails::Application - config.root = File.dirname(__FILE__) - config.logger = Logger.new($stdout) - Rails.logger = config.logger - - secrets.secret_token = 'secret_token' - secrets.secret_key_base = 'secret_key_base' - - # Define any models required to duplicate your issue - class YourModel < ActiveRecord::Base; end; - - # Define any ActiveAdmin configuration necessary to duplicate your issue - ActiveAdmin.setup do |config| - # Authentication disabled by default. Override if necessary - config.authentication_method = false - config.current_user_method = false - end - - ActiveAdmin.register_page 'Dashboard' do - content do - 'Test Me' - end - end - - # Set up your models as you have them in your ActiveAdmin config - ActiveAdmin.register YourModel do - end - - routes.draw do - ActiveAdmin.routes(self) - end -end - -require 'minitest/autorun' -require 'rack/test' - -# Replace this with the code necessary to make your test fail. -class BugTest < Minitest::Test - include Rack::Test::Methods - - def test_returns_success? - get '/admin' - assert last_response.ok? - end - - private - - def app - Rails.application - end -end diff --git a/lib/bug_report_templates/rails_5_master.rb b/lib/bug_report_templates/rails_5_master.rb new file mode 100644 index 00000000000..b0014c05b7d --- /dev/null +++ b/lib/bug_report_templates/rails_5_master.rb @@ -0,0 +1,120 @@ +begin + require 'bundler/inline' +rescue LoadError => e + STDERR.puts 'Bundler version 1.10 or later is required. Please update your Bundler' + raise e +end + +gemfile(true) do + source 'https://rubygems.org' + + gem 'rails', require: false + gem 'sqlite3', platform: :mri + + gem 'activerecord-jdbcsqlite3-adapter', + git: 'https://github.com/jruby/activerecord-jdbc-adapter', + branch: 'rails-5', + platform: :jruby + + if ENV['ACTIVE_ADMIN_PATH'] + gem 'activeadmin', path: ENV['ACTIVE_ADMIN_PATH'], require: false + else + gem 'activeadmin', git: 'https://github.com/activeadmin/activeadmin', require: false + end + + gem 'inherited_resources', '~> 1.7', require: false +end + +# prepare active_record database +require 'active_record' + +ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') +ActiveRecord::Base.logger = Logger.new(STDOUT) + +ActiveRecord::Schema.define do + create_table :active_admin_comments, force: true do |_t| + end + + # Add your schema here + create_table :your_models, force: true do |t| + t.string :name + end +end + +# prepare rails app +require 'action_controller/railtie' +require 'action_view/railtie' +require 'active_admin' + +class ApplicationController < ActionController::Base +end + +class TestApp < Rails::Application + config.root = File.dirname(__FILE__) + config.logger = Logger.new(STDOUT) + + secrets.secret_token = 'secret_token' + secrets.secret_key_base = 'secret_key_base' + + config.eager_load = false +end + +# create models +class YourModel < ActiveRecord::Base +end + +# configure active_admin +ActiveAdmin.setup do |config| + # Authentication disabled by default. Override if necessary + config.authentication_method = false + config.current_user_method = false +end + +# initialize app +Rails.application.initialize! + +# register pages and resources +ActiveAdmin.register_page 'Dashboard' do + menu priority: 1, label: proc { I18n.t('active_admin.dashboard') } + + content do + 'Test Me' + end +end + +ActiveAdmin.register YourModel do +end + +# draw active_admin routes +Rails.application.routes.draw do + ActiveAdmin.routes(self) +end + +# prepare tests +require 'minitest/autorun' +require 'rack/test' + +# Replace this with the code necessary to make your test fail. +class BugTest < Minitest::Test + include Rack::Test::Methods + + def test_admin_root_success? + get '/admin' + assert last_response.ok? + assert_match 'Test Me', last_response.body # has content + assert_match 'Your Models', last_response.body # has 'Your Models' in menu + end + + def test_admin_your_models + YourModel.create! name: 'John Doe' + get '/admin/your_models' + assert last_response.ok? + assert_match 'John Doe', last_response.body # has created row + end + + private + + def app + Rails.application + end +end diff --git a/spec/bug_report_templates_spec.rb b/spec/bug_report_templates_spec.rb new file mode 100644 index 00000000000..ef3abc34ce8 --- /dev/null +++ b/spec/bug_report_templates_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe 'bug_report_templates' do + subject do + Bundler.with_clean_env do + Dir.chdir(chdir_path) do + system({'ACTIVE_ADMIN_PATH' => active_admin_root}, Gem.ruby, template_path) + end + end + end + + let(:active_admin_root) { File.expand_path('../..', __FILE__) } + let(:chdir_path) { File.join(active_admin_root, 'lib', 'bug_report_templates') } + + context 'when runs rails_5_master.rb' do + let(:template_path) { 'rails_5_master.rb' } + + it 'passes' do + expect(subject).to be_truthy + end + end + + +end From 824aa184cb5ee4db6d6d7350cb7bdf18e8b0b793 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Tue, 7 Feb 2017 20:58:17 +0900 Subject: [PATCH 0301/3836] Apply the suffix adjustment in collection_path also to batch_action_path When the resource model name were an uncountable noun like "News", the URL helper method for the batch action would be suffixed with an extra `_index` suffix. We have confirmed that this fixes the following error you get with the current implementation when ActiveAdmin renders a batch action button: ``` Showing .../vendor/bundle/ruby/2.3.0/bundler/gems/activeadmin-6463e2b717b2/app/views/active_admin/resource/index.html.arb where line #2 raised: undefined method `batch_action_admin_news_path' for ActiveAdmin::Helpers::Routes:Module Did you mean? batch_action_admin_news_index_path ... ``` --- lib/active_admin/resource/routes.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/resource/routes.rb b/lib/active_admin/resource/routes.rb index 7831bb00b45..12c02d84dc5 100644 --- a/lib/active_admin/resource/routes.rb +++ b/lib/active_admin/resource/routes.rb @@ -51,8 +51,11 @@ def collection_path(params, additional_params = {}) end def batch_action_path(params, additional_params = {}) - path = resource.resources_configuration[:self][:route_collection_name] - route_name = route_name(path, action: :batch_action) + route_name = route_name( + resource.resources_configuration[:self][:route_collection_name], + action: :batch_action, + suffix: (resource.route_uncountable? ? "index_path" : "path") + ) query = params.slice(:q, :scope) query = query.permit! if query.respond_to? :permit! From b604345cd1aa9c5d3462c59272021978c2b18a83 Mon Sep 17 00:00:00 2001 From: Sakamoto Rumi Date: Thu, 9 Feb 2017 13:04:11 +0900 Subject: [PATCH 0302/3836] Comment route_name options[:action] is possible to be 'batch_action' --- lib/active_admin/resource/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/resource/routes.rb b/lib/active_admin/resource/routes.rb index 12c02d84dc5..2bca05617c3 100644 --- a/lib/active_admin/resource/routes.rb +++ b/lib/active_admin/resource/routes.rb @@ -90,7 +90,7 @@ def route_name(resource_path_name, options = {}) suffix = options[:suffix] || "path" route = [] - route << options[:action] # "edit" or "new" + route << options[:action] # "batch_action", "edit" or "new" route << resource.route_prefix # "admin" route += belongs_to_names route << resource_path_name # "posts" or "post" From 68f72cf04e8eb263742a8c16c92bd57c642be3f5 Mon Sep 17 00:00:00 2001 From: Sakamoto Rumi Date: Thu, 9 Feb 2017 13:05:06 +0900 Subject: [PATCH 0303/3836] Add spec batch_action handler for uncountable resource --- spec/unit/resource/routes_spec.rb | 40 +++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 7b95d708326..056f045d743 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -103,23 +103,39 @@ class ::News; def self.has_many(*); end end end context "for batch_action handler" do - let! :config do - ActiveAdmin.register Post do - belongs_to :category - end - end - before do - config.batch_actions= true + config.batch_actions = true reload_routes! end - it "should include :scope and :q params" do - params = { category_id: 1, q: { name_equals: "Any" }, scope: :all } - additional_params = { locale: 'en' } - batch_action_path = "/admin/categories/1/posts/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + context "when register a singular resource" do + + let! :config do + ActiveAdmin.register Post do + belongs_to :category + end + end + + it "should include :scope and :q params" do + params = { category_id: 1, q: { name_equals: "Any" }, scope: :all } + additional_params = { locale: 'en' } + batch_action_path = "/admin/categories/1/posts/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + + expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path + end + end + + context "when registering a plural resource" do - expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path + class ::News; def self.has_many(*); end end + let!(:config) { ActiveAdmin.register News } + + it "should return the plural batch action route with _index and given params" do + params = { q: { name_equals: "Any" }, scope: :all } + additional_params = { locale: 'en' } + batch_action_path = "/admin/news/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path + end end end end From 9b98c45b17dcf2c02aef99c8757e797b3659edca Mon Sep 17 00:00:00 2001 From: Jay Shepherd Date: Tue, 14 Feb 2017 20:44:11 -0600 Subject: [PATCH 0304/3836] Add filter for text_input to render text_area field --- lib/active_admin/inputs.rb | 1 + lib/active_admin/inputs/filters/text_input.rb | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 lib/active_admin/inputs/filters/text_input.rb diff --git a/lib/active_admin/inputs.rb b/lib/active_admin/inputs.rb index b634f4f2949..64f8e0e0831 100644 --- a/lib/active_admin/inputs.rb +++ b/lib/active_admin/inputs.rb @@ -9,6 +9,7 @@ module Filters autoload :Base autoload :StringInput + autoload :TextInput autoload :DatePickerInput autoload :DateRangeInput autoload :NumericInput diff --git a/lib/active_admin/inputs/filters/text_input.rb b/lib/active_admin/inputs/filters/text_input.rb new file mode 100644 index 00000000000..6126529beda --- /dev/null +++ b/lib/active_admin/inputs/filters/text_input.rb @@ -0,0 +1,26 @@ +module ActiveAdmin + module Inputs + module Filters + class TextInput < ::Formtastic::Inputs::TextInput + include Base + include Base::SearchMethodSelect + + def input_html_options + { + :cols => builder.default_text_area_width, + :rows => builder.default_text_area_height + }.merge(super) + end + + def to_html + input_wrapping do + label_html << + builder.text_area(method, input_html_options) + end + end + + end + end + end +end + From d0ea26a3b63633c98ef3964c77b9683ccdb5d506 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Mon, 13 Feb 2017 15:06:49 -0500 Subject: [PATCH 0305/3836] Call method on helpers instead of dispatching through Arbre::Element#method_missing. --- lib/active_admin/views/components/active_admin_form.rb | 2 +- lib/active_admin/views/components/attributes_table.rb | 2 +- lib/active_admin/views/components/site_title.rb | 4 ++-- lib/active_admin/views/components/table_for.rb | 4 ++-- lib/active_admin/views/pages/base.rb | 2 ++ lib/active_admin/views/pages/form.rb | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/active_admin/views/components/active_admin_form.rb b/lib/active_admin/views/components/active_admin_form.rb index 2d5202c9f31..8d0aac41c96 100644 --- a/lib/active_admin/views/components/active_admin_form.rb +++ b/lib/active_admin/views/components/active_admin_form.rb @@ -27,7 +27,7 @@ def build(resource, options = {}, &block) @resource = resource options = options.deep_dup options[:builder] ||= ActiveAdmin::FormBuilder - form_string = semantic_form_for(resource, options) do |f| + form_string = helpers.semantic_form_for(resource, options) do |f| @form_builder = f end diff --git a/lib/active_admin/views/components/attributes_table.rb b/lib/active_admin/views/components/attributes_table.rb index cfba14d9de6..592c34f450b 100644 --- a/lib/active_admin/views/components/attributes_table.rb +++ b/lib/active_admin/views/components/attributes_table.rb @@ -79,7 +79,7 @@ def empty_value end def content_for(record, attr) - value = format_attribute record, attr + value = helpers.format_attribute record, attr value.blank? && current_arbre_element.children.to_s.empty? ? empty_value : value # Don't add the same Arbre twice, while still allowing format_attribute to call status_tag current_arbre_element << value unless current_arbre_element.children.include? value diff --git a/lib/active_admin/views/components/site_title.rb b/lib/active_admin/views/components/site_title.rb index 9125765d4ba..b8be768d294 100644 --- a/lib/active_admin/views/components/site_title.rb +++ b/lib/active_admin/views/components/site_title.rb @@ -41,11 +41,11 @@ def site_title_content end def title_text - helpers.render_or_call_method_or_proc_on(self, @namespace.site_title) + helpers.render_or_call_method_or_proc_on(helpers, @namespace.site_title) end def title_image - path = helpers.render_or_call_method_or_proc_on(self, @namespace.site_title_image) + path = helpers.render_or_call_method_or_proc_on(helpers, @namespace.site_title_image) helpers.image_tag(path, id: "site_title_image", alt: title_text) end diff --git a/lib/active_admin/views/components/table_for.rb b/lib/active_admin/views/components/table_for.rb index fa392f24eec..5d60e59afd0 100644 --- a/lib/active_admin/views/components/table_for.rb +++ b/lib/active_admin/views/components/table_for.rb @@ -85,7 +85,7 @@ def build_table_body @tbody = tbody do # Build enough rows for our collection @collection.each do |elem| - classes = [cycle('odd', 'even')] + classes = [helpers.cycle('odd', 'even')] if @row_class classes << @row_class.call(elem) @@ -98,7 +98,7 @@ def build_table_body def build_table_cell(col, resource) td class: col.html_class do - html = format_attribute(resource, col.data) + html = helpers.format_attribute(resource, col.data) # Don't add the same Arbre twice, while still allowing format_attribute to call status_tag current_arbre_element << html unless current_arbre_element.children.include? html end diff --git a/lib/active_admin/views/pages/base.rb b/lib/active_admin/views/pages/base.rb index 0517159f021..db91ce94bce 100644 --- a/lib/active_admin/views/pages/base.rb +++ b/lib/active_admin/views/pages/base.rb @@ -12,6 +12,8 @@ def build(*args) private + delegate :active_admin_config, :controller, :params, to: :helpers + def add_classes_to_body @body.add_class(params[:action]) @body.add_class(params[:controller].tr('/', '_')) diff --git a/lib/active_admin/views/pages/form.rb b/lib/active_admin/views/pages/form.rb index 154279db7e6..5d0a4fa0623 100644 --- a/lib/active_admin/views/pages/form.rb +++ b/lib/active_admin/views/pages/form.rb @@ -6,7 +6,7 @@ class Form < Base def title if form_presenter[:title] - render_or_call_method_or_proc_on(resource, form_presenter[:title]) + helpers.render_or_call_method_or_proc_on(resource, form_presenter[:title]) else assigns[:page_title] || ActiveAdmin::Localizers.resource(active_admin_config).t("#{normalized_action}_model") end From 5c579a82aec42122dc77c20cb9ed2f86695581d2 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sat, 18 Feb 2017 01:03:24 +0200 Subject: [PATCH 0306/3836] configure rspec with disable_monkey_patching! see https://www.relishapp.com/rspec/rspec-core/v/3-0/docs/configuration/zero-monkey-patching-mode disable all monkey patching done by RSpec --- spec/bug_report_templates_spec.rb | 2 +- spec/rails_helper.rb | 1 + spec/requests/default_namespace_spec.rb | 40 +++++++++---------- spec/requests/javascript_spec.rb | 2 +- spec/requests/memory_spec.rb | 2 +- spec/requests/stylesheets_spec.rb | 2 +- spec/unit/abstract_view_factory_spec.rb | 2 +- spec/unit/action_builder_spec.rb | 2 +- spec/unit/active_admin_spec.rb | 2 +- spec/unit/application_spec.rb | 2 +- spec/unit/asset_registration_spec.rb | 2 +- .../authorization_adapter_spec.rb | 2 +- .../controller_authorization_spec.rb | 2 +- .../authorization/index_overriding_spec.rb | 2 +- spec/unit/auto_link_spec.rb | 2 +- spec/unit/batch_actions/resource_spec.rb | 2 +- spec/unit/batch_actions/settings_spec.rb | 2 +- spec/unit/belongs_to_spec.rb | 2 +- spec/unit/cancan_adapter_spec.rb | 2 +- spec/unit/comments_spec.rb | 2 +- spec/unit/component_spec.rb | 2 +- spec/unit/config_shared_examples.rb | 4 +- spec/unit/controller_filters_spec.rb | 2 +- spec/unit/csv_builder_spec.rb | 2 +- spec/unit/dependency_spec.rb | 2 +- spec/unit/devise_spec.rb | 2 +- spec/unit/dsl_spec.rb | 2 +- spec/unit/filters/active_spec.rb | 4 +- spec/unit/filters/filter_form_builder_spec.rb | 2 +- spec/unit/filters/humanized_spec.rb | 2 +- spec/unit/filters/resource_spec.rb | 2 +- spec/unit/form_builder_spec.rb | 2 +- spec/unit/generators/install_spec.rb | 2 +- spec/unit/helpers/collection_spec.rb | 2 +- spec/unit/helpers/scope_chain_spec.rb | 2 +- spec/unit/helpers/settings_spec.rb | 2 +- spec/unit/i18n_spec.rb | 2 +- .../localizers/resource_localizer_spec.rb | 2 +- spec/unit/menu_collection_spec.rb | 2 +- spec/unit/menu_item_spec.rb | 2 +- spec/unit/menu_spec.rb | 2 +- spec/unit/namespace/authorization_spec.rb | 2 +- spec/unit/namespace/register_page_spec.rb | 2 +- spec/unit/namespace/register_resource_spec.rb | 2 +- spec/unit/namespace_spec.rb | 2 +- spec/unit/order_clause_spec.rb | 2 +- spec/unit/page_controller_spec.rb | 2 +- spec/unit/page_spec.rb | 2 +- spec/unit/pretty_format_spec.rb | 2 +- spec/unit/pundit_adapter_spec.rb | 2 +- spec/unit/resource/action_items_spec.rb | 2 +- spec/unit/resource/includes_spec.rb | 2 +- spec/unit/resource/menu_spec.rb | 2 +- spec/unit/resource/naming_spec.rb | 2 +- spec/unit/resource/ordering_spec.rb | 2 +- spec/unit/resource/page_presenters_spec.rb | 2 +- spec/unit/resource/pagination_spec.rb | 2 +- spec/unit/resource/routes_spec.rb | 2 +- spec/unit/resource/scopes_spec.rb | 2 +- spec/unit/resource/sidebars_spec.rb | 2 +- spec/unit/resource_collection_spec.rb | 2 +- .../resource_controller/data_access_spec.rb | 2 +- .../resource_controller/decorators_spec.rb | 2 +- .../unit/resource_controller/sidebars_spec.rb | 2 +- spec/unit/resource_controller_spec.rb | 4 +- spec/unit/resource_registration_spec.rb | 2 +- spec/unit/resource_spec.rb | 2 +- spec/unit/routing_spec.rb | 2 +- spec/unit/scope_spec.rb | 2 +- spec/unit/settings_spec.rb | 4 +- spec/unit/view_factory_spec.rb | 2 +- spec/unit/view_helpers/breadcrumbs_spec.rb | 2 +- spec/unit/view_helpers/display_helper_spec.rb | 2 +- .../download_format_links_helper_spec.rb | 2 +- spec/unit/view_helpers/fields_for_spec.rb | 2 +- spec/unit/view_helpers/flash_helper_spec.rb | 2 +- spec/unit/view_helpers/form_helper_spec.rb | 2 +- .../method_or_proc_helper_spec.rb | 2 +- .../views/components/attributes_table_spec.rb | 2 +- .../components/batch_action_selector_spec.rb | 2 +- .../unit/views/components/blank_slate_spec.rb | 2 +- spec/unit/views/components/columns_spec.rb | 2 +- spec/unit/views/components/index_list_spec.rb | 2 +- .../views/components/index_table_for_spec.rb | 2 +- .../components/paginated_collection_spec.rb | 2 +- spec/unit/views/components/panel_spec.rb | 2 +- .../views/components/sidebar_section_spec.rb | 2 +- spec/unit/views/components/site_title_spec.rb | 2 +- spec/unit/views/components/status_tag_spec.rb | 2 +- spec/unit/views/components/table_for_spec.rb | 2 +- spec/unit/views/components/tabs_spec.rb | 2 +- .../components/unsupported_browser_spec.rb | 2 +- spec/unit/views/index_as_blog_spec.rb | 2 +- spec/unit/views/pages/form_spec.rb | 2 +- spec/unit/views/pages/index_spec.rb | 2 +- spec/unit/views/pages/layout_spec.rb | 2 +- spec/unit/views/pages/show_spec.rb | 2 +- spec/unit/views/tabbed_navigation_spec.rb | 2 +- 98 files changed, 121 insertions(+), 120 deletions(-) diff --git a/spec/bug_report_templates_spec.rb b/spec/bug_report_templates_spec.rb index ef3abc34ce8..316831f2999 100644 --- a/spec/bug_report_templates_spec.rb +++ b/spec/bug_report_templates_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'bug_report_templates' do +RSpec.describe 'bug_report_templates' do subject do Bundler.with_clean_env do Dir.chdir(chdir_path) do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index afa7824460d..6ece4608d34 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -101,6 +101,7 @@ def with_translation(translation) ActiveAdmin.application.current_user_method = false RSpec.configure do |config| + config.disable_monkey_patching! config.use_transactional_fixtures = true config.use_instantiated_fixtures = false config.render_views = false diff --git a/spec/requests/default_namespace_spec.rb b/spec/requests/default_namespace_spec.rb index e9d618742d0..fa1b4cc6d1e 100644 --- a/spec/requests/default_namespace_spec.rb +++ b/spec/requests/default_namespace_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Application, type: :request do +RSpec.describe ActiveAdmin::Application, type: :request do include Rails.application.routes.url_helpers @@ -33,29 +33,29 @@ end - describe "with a test default namespace" do + describe "with a test default namespace" do - before(:all) do - @__original_application = ActiveAdmin.application - application = ActiveAdmin::Application.new - application.default_namespace = :test - ActiveAdmin.application = application - load_defaults! - reload_routes! - end - - after(:all) do - ActiveAdmin.application = @__original_application - end + before(:all) do + @__original_application = ActiveAdmin.application + application = ActiveAdmin::Application.new + application.default_namespace = :test + ActiveAdmin.application = application + load_defaults! + reload_routes! + end - it "should generate a log out path" do - expect(destroy_admin_user_session_path).to eq "/test/logout" - end + after(:all) do + ActiveAdmin.application = @__original_application + end - it "should generate a log in path" do - expect(new_admin_user_session_path).to eq "/test/login" - end + it "should generate a log out path" do + expect(destroy_admin_user_session_path).to eq "/test/logout" + end + it "should generate a log in path" do + expect(new_admin_user_session_path).to eq "/test/login" end + end + end diff --git a/spec/requests/javascript_spec.rb b/spec/requests/javascript_spec.rb index 8d41b4edb95..d0c2bd4597a 100644 --- a/spec/requests/javascript_spec.rb +++ b/spec/requests/javascript_spec.rb @@ -7,7 +7,7 @@ RbConfig::CONFIG['host_os'].include?('darwin') ? `/usr/libexec/java_home` : `which java` java_installed = $?.success? -describe 'Javascript', type: :request, if: java_installed do +RSpec.describe 'Javascript', type: :request, if: java_installed do let(:lint) { JSLint::Lint.new \ paths: ['public/javascripts/**/*.js'], diff --git a/spec/requests/memory_spec.rb b/spec/requests/memory_spec.rb index 4594f513f85..755d385b3fc 100644 --- a/spec/requests/memory_spec.rb +++ b/spec/requests/memory_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "Memory Leak", type: :request, if: RUBY_ENGINE == 'ruby' do +RSpec.describe "Memory Leak", type: :request, if: RUBY_ENGINE == 'ruby' do def count_instances_of(klass) ObjectSpace.each_object(klass) { } end diff --git a/spec/requests/stylesheets_spec.rb b/spec/requests/stylesheets_spec.rb index 1fea493c1a9..f008baa8b5b 100644 --- a/spec/requests/stylesheets_spec.rb +++ b/spec/requests/stylesheets_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "Stylesheets", type: :request do +RSpec.describe "Stylesheets", type: :request do require "sprockets" diff --git a/spec/unit/abstract_view_factory_spec.rb b/spec/unit/abstract_view_factory_spec.rb index 8a9bb0c9b8b..6ecc3fd4d61 100644 --- a/spec/unit/abstract_view_factory_spec.rb +++ b/spec/unit/abstract_view_factory_spec.rb @@ -2,7 +2,7 @@ require 'active_admin/abstract_view_factory' -describe ActiveAdmin::AbstractViewFactory do +RSpec.describe ActiveAdmin::AbstractViewFactory do let(:view_factory){ ActiveAdmin::AbstractViewFactory.new } let(:view){ Class.new } diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb index 8c29de44ad1..a1c0531ec8d 100644 --- a/spec/unit/action_builder_spec.rb +++ b/spec/unit/action_builder_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe 'defining actions from registration blocks', type: :controller do +RSpec.describe 'defining actions from registration blocks', type: :controller do let(:klass){ Admin::PostsController } render_views # https://github.com/rspec/rspec-rails/issues/860 diff --git a/spec/unit/active_admin_spec.rb b/spec/unit/active_admin_spec.rb index 326c2da2f70..e1ec9ea035c 100644 --- a/spec/unit/active_admin_spec.rb +++ b/spec/unit/active_admin_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin do +RSpec.describe ActiveAdmin do %w(register register_page unload! load! routes).each do |method| it "delegates ##{method} to application" do expect(ActiveAdmin.application).to receive(method) diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index 7a0aae7ac14..2020a3280c8 100644 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'fileutils' -describe ActiveAdmin::Application do +RSpec.describe ActiveAdmin::Application do let(:application) do ActiveAdmin::Application.new.tap do |app| diff --git a/spec/unit/asset_registration_spec.rb b/spec/unit/asset_registration_spec.rb index 441c8d999db..740a4ddd3ba 100644 --- a/spec/unit/asset_registration_spec.rb +++ b/spec/unit/asset_registration_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::AssetRegistration do +RSpec.describe ActiveAdmin::AssetRegistration do include ActiveAdmin::AssetRegistration before do diff --git a/spec/unit/authorization/authorization_adapter_spec.rb b/spec/unit/authorization/authorization_adapter_spec.rb index 17c3a075781..7bc51e683a1 100644 --- a/spec/unit/authorization/authorization_adapter_spec.rb +++ b/spec/unit/authorization/authorization_adapter_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::AuthorizationAdapter do +RSpec.describe ActiveAdmin::AuthorizationAdapter do let(:adapter) { ActiveAdmin::AuthorizationAdapter.new(double, double) } diff --git a/spec/unit/authorization/controller_authorization_spec.rb b/spec/unit/authorization/controller_authorization_spec.rb index f8b05bb7c3f..c014229a07f 100644 --- a/spec/unit/authorization/controller_authorization_spec.rb +++ b/spec/unit/authorization/controller_authorization_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' Auth = ActiveAdmin::Authorization -describe Admin::PostsController, "Controller Authorization", type: :controller do +RSpec.describe Admin::PostsController, "Controller Authorization", type: :controller do let(:authorization){ controller.send(:active_admin_authorization) } diff --git a/spec/unit/authorization/index_overriding_spec.rb b/spec/unit/authorization/index_overriding_spec.rb index 40377284007..c1b57678cac 100644 --- a/spec/unit/authorization/index_overriding_spec.rb +++ b/spec/unit/authorization/index_overriding_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe Admin::PostsController, 'Index overriding', type: :controller do +RSpec.describe Admin::PostsController, 'Index overriding', type: :controller do before do controller.instance_eval do def index diff --git a/spec/unit/auto_link_spec.rb b/spec/unit/auto_link_spec.rb index 85ba0fb41d2..aea58f60f03 100644 --- a/spec/unit/auto_link_spec.rb +++ b/spec/unit/auto_link_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "auto linking resources" do +RSpec.describe "auto linking resources" do include ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper include ActiveAdmin::ViewHelpers::AutoLinkHelper include ActiveAdmin::ViewHelpers::DisplayHelper diff --git a/spec/unit/batch_actions/resource_spec.rb b/spec/unit/batch_actions/resource_spec.rb index 5fd3152b158..1489e9e7a8f 100644 --- a/spec/unit/batch_actions/resource_spec.rb +++ b/spec/unit/batch_actions/resource_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::BatchActions::ResourceExtension do +RSpec.describe ActiveAdmin::BatchActions::ResourceExtension do let(:resource) do namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) diff --git a/spec/unit/batch_actions/settings_spec.rb b/spec/unit/batch_actions/settings_spec.rb index 4cb186169cb..716c4d56b4e 100644 --- a/spec/unit/batch_actions/settings_spec.rb +++ b/spec/unit/batch_actions/settings_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "Batch Actions Settings" do +RSpec.describe "Batch Actions Settings" do let(:app) { ActiveAdmin::Application.new } let(:ns) { ActiveAdmin::Namespace.new(app, "Admin") } let(:post_resource) { ns.register Post } diff --git a/spec/unit/belongs_to_spec.rb b/spec/unit/belongs_to_spec.rb index d675c67b5af..611bf650b8f 100644 --- a/spec/unit/belongs_to_spec.rb +++ b/spec/unit/belongs_to_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Resource::BelongsTo do +RSpec.describe ActiveAdmin::Resource::BelongsTo do let(:user_config){ ActiveAdmin.register User } let(:post_config){ ActiveAdmin.register Post do belongs_to :user end } diff --git a/spec/unit/cancan_adapter_spec.rb b/spec/unit/cancan_adapter_spec.rb index 675af3df3cc..88082c90355 100644 --- a/spec/unit/cancan_adapter_spec.rb +++ b/spec/unit/cancan_adapter_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::CanCanAdapter do +RSpec.describe ActiveAdmin::CanCanAdapter do describe "full integration" do diff --git a/spec/unit/comments_spec.rb b/spec/unit/comments_spec.rb index 0272181f95c..5dc7ef190c9 100644 --- a/spec/unit/comments_spec.rb +++ b/spec/unit/comments_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "Comments" do +RSpec.describe "Comments" do let(:application) { ActiveAdmin::Application.new } describe ActiveAdmin::Comment do diff --git a/spec/unit/component_spec.rb b/spec/unit/component_spec.rb index efeade7edaa..82a77ba5ced 100644 --- a/spec/unit/component_spec.rb +++ b/spec/unit/component_spec.rb @@ -2,7 +2,7 @@ class MockComponentClass < ActiveAdmin::Component; end -describe ActiveAdmin::Component do +RSpec.describe ActiveAdmin::Component do let(:component_class){ MockComponentClass } let(:component){ component_class.new } diff --git a/spec/unit/config_shared_examples.rb b/spec/unit/config_shared_examples.rb index 90317c18638..696eac52b6e 100644 --- a/spec/unit/config_shared_examples.rb +++ b/spec/unit/config_shared_examples.rb @@ -1,4 +1,4 @@ -shared_examples_for "ActiveAdmin::Resource" do +RSpec.shared_examples_for "ActiveAdmin::Resource" do describe "namespace" do it "should return the namespace" do expect(config.namespace).to eq(namespace) @@ -58,7 +58,7 @@ end end -shared_examples_for "ActiveAdmin::Localizers::ResourceLocalizer" do +RSpec.shared_examples_for "ActiveAdmin::Localizers::ResourceLocalizer" do it "should use proper translation" do string = ActiveAdmin::Localizers::ResourceLocalizer.t(action, model: model, model_name: model_name) expect(string).to eq translation diff --git a/spec/unit/controller_filters_spec.rb b/spec/unit/controller_filters_spec.rb index 28ed564a008..a7b828759be 100644 --- a/spec/unit/controller_filters_spec.rb +++ b/spec/unit/controller_filters_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Application do +RSpec.describe ActiveAdmin::Application do let(:application){ ActiveAdmin::Application.new } let(:controllers){ application.controllers_for_filters } diff --git a/spec/unit/csv_builder_spec.rb b/spec/unit/csv_builder_spec.rb index f554e888dd1..7cc14704895 100644 --- a/spec/unit/csv_builder_spec.rb +++ b/spec/unit/csv_builder_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe ActiveAdmin::CSVBuilder do +RSpec.describe ActiveAdmin::CSVBuilder do describe '.default_for_resource using Post' do let(:csv_builder) { ActiveAdmin::CSVBuilder.default_for_resource(Post).tap(&:exec_columns) } diff --git a/spec/unit/dependency_spec.rb b/spec/unit/dependency_spec.rb index c0a798ebb84..fec4b6d6847 100644 --- a/spec/unit/dependency_spec.rb +++ b/spec/unit/dependency_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Dependency do +RSpec.describe ActiveAdmin::Dependency do k = ActiveAdmin::Dependency diff --git a/spec/unit/devise_spec.rb b/spec/unit/devise_spec.rb index 9c8bff9da4f..f45bc1dbe33 100644 --- a/spec/unit/devise_spec.rb +++ b/spec/unit/devise_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Devise::Controller do +RSpec.describe ActiveAdmin::Devise::Controller do let(:controller_class) do klass = Class.new do diff --git a/spec/unit/dsl_spec.rb b/spec/unit/dsl_spec.rb index ec599efb3d2..1f79cee384d 100644 --- a/spec/unit/dsl_spec.rb +++ b/spec/unit/dsl_spec.rb @@ -6,7 +6,7 @@ def self.included(dsl) end end -describe ActiveAdmin::DSL do +RSpec.describe ActiveAdmin::DSL do let(:application) { ActiveAdmin::Application.new } let(:namespace) { ActiveAdmin::Namespace.new application, :admin } diff --git a/spec/unit/filters/active_spec.rb b/spec/unit/filters/active_spec.rb index 1469fd01d3a..767300748f1 100644 --- a/spec/unit/filters/active_spec.rb +++ b/spec/unit/filters/active_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Filters::Active do +RSpec.describe ActiveAdmin::Filters::Active do subject { described_class.new(Post, params) } let(:params_klass) do if defined? ::ActionController::Parameters @@ -18,4 +18,4 @@ expect(subject.filters.size).to eq(1) end -end \ No newline at end of file +end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 34f9585e6c5..f14d5d85da8 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -12,7 +12,7 @@ class Post end end -describe ActiveAdmin::Filters::ViewHelper do +RSpec.describe ActiveAdmin::Filters::ViewHelper do # Setup an ActionView::Base object which can be used for # generating the form for. diff --git a/spec/unit/filters/humanized_spec.rb b/spec/unit/filters/humanized_spec.rb index 043656b92b3..4204d2326ea 100644 --- a/spec/unit/filters/humanized_spec.rb +++ b/spec/unit/filters/humanized_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Filters::Humanized do +RSpec.describe ActiveAdmin::Filters::Humanized do describe '#value' do it 'should equal query string parameter if not an Array' do param = ['category_id_eq', '1'] diff --git a/spec/unit/filters/resource_spec.rb b/spec/unit/filters/resource_spec.rb index 6bc920de21f..f2821ff4e85 100644 --- a/spec/unit/filters/resource_spec.rb +++ b/spec/unit/filters/resource_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Filters::ResourceExtension do +RSpec.describe ActiveAdmin::Filters::ResourceExtension do let(:resource) do namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 15b60699322..f98ac6ba024 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require "rspec/mocks/standalone" -describe ActiveAdmin::FormBuilder do +RSpec.describe ActiveAdmin::FormBuilder do # Setup an ActionView::Base object which can be used for # generating the form for. let(:helpers) do diff --git a/spec/unit/generators/install_spec.rb b/spec/unit/generators/install_spec.rb index e1cdb69dc31..d1fbdb85b58 100644 --- a/spec/unit/generators/install_spec.rb +++ b/spec/unit/generators/install_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "AA installation" do +RSpec.describe "AA installation" do context "should create" do it "active_admin.scss" do diff --git a/spec/unit/helpers/collection_spec.rb b/spec/unit/helpers/collection_spec.rb index 30cc227f5c2..90f1ed53d70 100644 --- a/spec/unit/helpers/collection_spec.rb +++ b/spec/unit/helpers/collection_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Helpers::Collection do +RSpec.describe ActiveAdmin::Helpers::Collection do include ActiveAdmin::Helpers::Collection diff --git a/spec/unit/helpers/scope_chain_spec.rb b/spec/unit/helpers/scope_chain_spec.rb index 47f107f0e06..d4041addbc5 100644 --- a/spec/unit/helpers/scope_chain_spec.rb +++ b/spec/unit/helpers/scope_chain_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ScopeChain do +RSpec.describe ActiveAdmin::ScopeChain do include ActiveAdmin::ScopeChain diff --git a/spec/unit/helpers/settings_spec.rb b/spec/unit/helpers/settings_spec.rb index aceea47dc5c..506d1bc65af 100644 --- a/spec/unit/helpers/settings_spec.rb +++ b/spec/unit/helpers/settings_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'active_admin/helpers/settings' -describe ActiveAdmin::Settings do +RSpec.describe ActiveAdmin::Settings do # A Class with settings module included let(:klass) do diff --git a/spec/unit/i18n_spec.rb b/spec/unit/i18n_spec.rb index 0480e4f1f0e..1cadd8aa252 100644 --- a/spec/unit/i18n_spec.rb +++ b/spec/unit/i18n_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' Dir.glob('config/locales/*.yml') do |locale_file| - describe locale_file do + RSpec.describe locale_file do it { is_expected.to be_parseable } it { is_expected.to have_one_top_level_namespace } it { is_expected.to be_named_like_top_level_namespace } diff --git a/spec/unit/localizers/resource_localizer_spec.rb b/spec/unit/localizers/resource_localizer_spec.rb index cc696123cb8..3ebf6185395 100644 --- a/spec/unit/localizers/resource_localizer_spec.rb +++ b/spec/unit/localizers/resource_localizer_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require File.expand_path('../config_shared_examples', File.dirname(__FILE__)) -describe ActiveAdmin::Localizers::ResourceLocalizer do +RSpec.describe ActiveAdmin::Localizers::ResourceLocalizer do let(:action) { 'new_model' } let(:model) { 'Comment' } let(:model_name) { 'comment' } diff --git a/spec/unit/menu_collection_spec.rb b/spec/unit/menu_collection_spec.rb index b01f4b95635..67163b0c77c 100644 --- a/spec/unit/menu_collection_spec.rb +++ b/spec/unit/menu_collection_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::MenuCollection do +RSpec.describe ActiveAdmin::MenuCollection do let(:menus) { ActiveAdmin::MenuCollection.new } diff --git a/spec/unit/menu_item_spec.rb b/spec/unit/menu_item_spec.rb index b8da10a353c..ecc43d74035 100644 --- a/spec/unit/menu_item_spec.rb +++ b/spec/unit/menu_item_spec.rb @@ -3,7 +3,7 @@ require 'active_admin/menu_item' module ActiveAdmin - describe MenuItem do + RSpec.describe MenuItem do it "should have a label" do item = MenuItem.new(label: "Dashboard") diff --git a/spec/unit/menu_spec.rb b/spec/unit/menu_spec.rb index b553804e5c7..821c88cbfd5 100644 --- a/spec/unit/menu_spec.rb +++ b/spec/unit/menu_spec.rb @@ -4,7 +4,7 @@ include ActiveAdmin -describe ActiveAdmin::Menu do +RSpec.describe ActiveAdmin::Menu do context "with no items" do it "should have an empty item collection" do diff --git a/spec/unit/namespace/authorization_spec.rb b/spec/unit/namespace/authorization_spec.rb index 445359f76f2..8f0080f0c33 100644 --- a/spec/unit/namespace/authorization_spec.rb +++ b/spec/unit/namespace/authorization_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Resource, "authorization" do +RSpec.describe ActiveAdmin::Resource, "authorization" do let(:app){ ActiveAdmin::Application.new } let(:namespace){ ActiveAdmin::Namespace.new(app, :admin) } diff --git a/spec/unit/namespace/register_page_spec.rb b/spec/unit/namespace/register_page_spec.rb index 2572037f414..c0464a809a2 100644 --- a/spec/unit/namespace/register_page_spec.rb +++ b/spec/unit/namespace/register_page_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Namespace, "registering a page" do +RSpec.describe ActiveAdmin::Namespace, "registering a page" do let(:application){ ActiveAdmin::Application.new } let(:namespace){ ActiveAdmin::Namespace.new(application, :admin) } let(:menu){ namespace.fetch_menu(:default) } diff --git a/spec/unit/namespace/register_resource_spec.rb b/spec/unit/namespace/register_resource_spec.rb index 7f940b56884..c5e335c930a 100644 --- a/spec/unit/namespace/register_resource_spec.rb +++ b/spec/unit/namespace/register_resource_spec.rb @@ -3,7 +3,7 @@ # TODO: refactor this file so it doesn't depend on the Admin namespace in such a broken way. # Specifically, the dashboard is already defined. -describe ActiveAdmin::Namespace, "registering a resource" do +RSpec.describe ActiveAdmin::Namespace, "registering a resource" do let(:application){ ActiveAdmin::Application.new } let(:namespace){ ActiveAdmin::Namespace.new(application, :admin) } let(:menu){ namespace.fetch_menu(:default) } diff --git a/spec/unit/namespace_spec.rb b/spec/unit/namespace_spec.rb index 75928625186..21ca33de9d5 100644 --- a/spec/unit/namespace_spec.rb +++ b/spec/unit/namespace_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Namespace do +RSpec.describe ActiveAdmin::Namespace do let(:application){ ActiveAdmin::Application.new } diff --git a/spec/unit/order_clause_spec.rb b/spec/unit/order_clause_spec.rb index db4da29befd..f791bad7449 100644 --- a/spec/unit/order_clause_spec.rb +++ b/spec/unit/order_clause_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::OrderClause do +RSpec.describe ActiveAdmin::OrderClause do subject { described_class.new(config, clause) } let(:application) { ActiveAdmin::Application.new } diff --git a/spec/unit/page_controller_spec.rb b/spec/unit/page_controller_spec.rb index 0d5ad5465c2..9a9cbe3d29d 100644 --- a/spec/unit/page_controller_spec.rb +++ b/spec/unit/page_controller_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -describe ActiveAdmin::PageController do +RSpec.describe ActiveAdmin::PageController do let(:controller) { ActiveAdmin::PageController.new } end diff --git a/spec/unit/page_spec.rb b/spec/unit/page_spec.rb index 0ff3cbf5b64..9405db94887 100644 --- a/spec/unit/page_spec.rb +++ b/spec/unit/page_spec.rb @@ -4,7 +4,7 @@ require File.expand_path('config_shared_examples', File.dirname(__FILE__)) module ActiveAdmin - describe Page do + RSpec.describe Page do it_should_behave_like "ActiveAdmin::Resource" before { load_defaults! } diff --git a/spec/unit/pretty_format_spec.rb b/spec/unit/pretty_format_spec.rb index c1b3634d0f9..0b06ee80dba 100644 --- a/spec/unit/pretty_format_spec.rb +++ b/spec/unit/pretty_format_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "#pretty_format" do +RSpec.describe "#pretty_format" do include ActiveAdmin::ViewHelpers::DisplayHelper def method_missing(*args, &block) diff --git a/spec/unit/pundit_adapter_spec.rb b/spec/unit/pundit_adapter_spec.rb index 1f02c66c9e1..c1bdab06422 100644 --- a/spec/unit/pundit_adapter_spec.rb +++ b/spec/unit/pundit_adapter_spec.rb @@ -28,7 +28,7 @@ def resolve end end -describe ActiveAdmin::PunditAdapter do +RSpec.describe ActiveAdmin::PunditAdapter do describe "full integration" do diff --git a/spec/unit/resource/action_items_spec.rb b/spec/unit/resource/action_items_spec.rb index 53d7a149d91..5ea839fcb59 100644 --- a/spec/unit/resource/action_items_spec.rb +++ b/spec/unit/resource/action_items_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Resource::ActionItems do +RSpec.describe ActiveAdmin::Resource::ActionItems do let(:resource) do namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) diff --git a/spec/unit/resource/includes_spec.rb b/spec/unit/resource/includes_spec.rb index f38542591b4..92e77124083 100644 --- a/spec/unit/resource/includes_spec.rb +++ b/spec/unit/resource/includes_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' module ActiveAdmin - describe Resource, "Includes" do + RSpec.describe Resource, "Includes" do describe "#includes" do let(:application) { ActiveAdmin::Application.new } diff --git a/spec/unit/resource/menu_spec.rb b/spec/unit/resource/menu_spec.rb index 17f6ee7648b..2ab8a2e570d 100644 --- a/spec/unit/resource/menu_spec.rb +++ b/spec/unit/resource/menu_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' module ActiveAdmin - describe Resource, "Menu" do + RSpec.describe Resource, "Menu" do before { load_defaults! } diff --git a/spec/unit/resource/naming_spec.rb b/spec/unit/resource/naming_spec.rb index 81d06c88221..42330f0dee7 100644 --- a/spec/unit/resource/naming_spec.rb +++ b/spec/unit/resource/naming_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' module ActiveAdmin - describe Resource, "Naming" do + RSpec.describe Resource, "Naming" do before { load_defaults! } diff --git a/spec/unit/resource/ordering_spec.rb b/spec/unit/resource/ordering_spec.rb index 1a230172b26..42d830a92a7 100644 --- a/spec/unit/resource/ordering_spec.rb +++ b/spec/unit/resource/ordering_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' module ActiveAdmin - describe Resource, "Ordering" do + RSpec.describe Resource, "Ordering" do describe "#order_by" do let(:application) { ActiveAdmin::Application.new } diff --git a/spec/unit/resource/page_presenters_spec.rb b/spec/unit/resource/page_presenters_spec.rb index 166bdced717..ae0bce688c4 100644 --- a/spec/unit/resource/page_presenters_spec.rb +++ b/spec/unit/resource/page_presenters_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Resource::PagePresenters do +RSpec.describe ActiveAdmin::Resource::PagePresenters do let(:namespace){ ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) } let(:resource){ namespace.register(Post) } diff --git a/spec/unit/resource/pagination_spec.rb b/spec/unit/resource/pagination_spec.rb index 15be663844f..940c298bf0b 100644 --- a/spec/unit/resource/pagination_spec.rb +++ b/spec/unit/resource/pagination_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' module ActiveAdmin - describe Resource, "Pagination" do + RSpec.describe Resource, "Pagination" do before { load_defaults! } diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 056f045d743..abdd55a26c0 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' module ActiveAdmin - describe Resource::Routes do + RSpec.describe Resource::Routes do after do load_defaults! diff --git a/spec/unit/resource/scopes_spec.rb b/spec/unit/resource/scopes_spec.rb index 1a02f855bac..4014c4a3d69 100644 --- a/spec/unit/resource/scopes_spec.rb +++ b/spec/unit/resource/scopes_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' module ActiveAdmin - describe Resource, "Scopes" do + RSpec.describe Resource, "Scopes" do before { load_defaults! } diff --git a/spec/unit/resource/sidebars_spec.rb b/spec/unit/resource/sidebars_spec.rb index 94289631653..85496e4a5b3 100644 --- a/spec/unit/resource/sidebars_spec.rb +++ b/spec/unit/resource/sidebars_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Resource::Sidebars do +RSpec.describe ActiveAdmin::Resource::Sidebars do let(:resource) do namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb index 56881f06754..0a3f92ad839 100644 --- a/spec/unit/resource_collection_spec.rb +++ b/spec/unit/resource_collection_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'active_admin/resource_collection' -describe ActiveAdmin::ResourceCollection do +RSpec.describe ActiveAdmin::ResourceCollection do let(:application) { ActiveAdmin::Application.new } let(:namespace) { ActiveAdmin::Namespace.new application, :admin } let(:collection) { ActiveAdmin::ResourceCollection.new } diff --git a/spec/unit/resource_controller/data_access_spec.rb b/spec/unit/resource_controller/data_access_spec.rb index 5fbc781b330..c2b64292029 100644 --- a/spec/unit/resource_controller/data_access_spec.rb +++ b/spec/unit/resource_controller/data_access_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ResourceController::DataAccess do +RSpec.describe ActiveAdmin::ResourceController::DataAccess do let(:params) do {} end diff --git a/spec/unit/resource_controller/decorators_spec.rb b/spec/unit/resource_controller/decorators_spec.rb index 1fa822394bd..5cc5d77b070 100644 --- a/spec/unit/resource_controller/decorators_spec.rb +++ b/spec/unit/resource_controller/decorators_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ResourceController::Decorators do +RSpec.describe ActiveAdmin::ResourceController::Decorators do let(:controller_class) do Class.new do def self.name diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index 28bed17cb02..34616e64e06 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ResourceController::Sidebars, type: :controller do +RSpec.describe ActiveAdmin::ResourceController::Sidebars, type: :controller do let(:klass){ Admin::PostsController } render_views # https://github.com/rspec/rspec-rails/issues/860 diff --git a/spec/unit/resource_controller_spec.rb b/spec/unit/resource_controller_spec.rb index 71cabeab813..f7b52623b53 100644 --- a/spec/unit/resource_controller_spec.rb +++ b/spec/unit/resource_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ResourceController do +RSpec.describe ActiveAdmin::ResourceController do let(:controller) { ActiveAdmin::ResourceController.new } @@ -155,7 +155,7 @@ def call_after_destroy(obj); end end end -describe Admin::PostsController, type: "controller" do +RSpec.describe Admin::PostsController, type: "controller" do describe 'retrieving the resource' do let(:controller){ Admin::PostsController.new } diff --git a/spec/unit/resource_registration_spec.rb b/spec/unit/resource_registration_spec.rb index 43022fedf12..7d5facc4d66 100644 --- a/spec/unit/resource_registration_spec.rb +++ b/spec/unit/resource_registration_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "Registering an object to administer" do +RSpec.describe "Registering an object to administer" do application = ActiveAdmin::Application.new context "with no configuration" do diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index 27e3a75551b..d641457b4a1 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -2,7 +2,7 @@ require File.expand_path('config_shared_examples', File.dirname(__FILE__)) module ActiveAdmin - describe Resource do + RSpec.describe Resource do it_should_behave_like "ActiveAdmin::Resource" before { load_defaults! } diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index 9af60e1c083..b307cd05a7a 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe ActiveAdmin, "Routing", type: :routing do +RSpec.describe ActiveAdmin, "Routing", type: :routing do before do load_defaults! diff --git a/spec/unit/scope_spec.rb b/spec/unit/scope_spec.rb index 77744f30986..1c1593f7bee 100644 --- a/spec/unit/scope_spec.rb +++ b/spec/unit/scope_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Scope do +RSpec.describe ActiveAdmin::Scope do describe "creating a scope" do subject{ scope } diff --git a/spec/unit/settings_spec.rb b/spec/unit/settings_spec.rb index 709843f3a64..592f6df79d2 100644 --- a/spec/unit/settings_spec.rb +++ b/spec/unit/settings_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Settings do +RSpec.describe ActiveAdmin::Settings do subject{ Class.new{ include ActiveAdmin::Settings } } @@ -46,7 +46,7 @@ end -describe ActiveAdmin::Settings::Inheritance do +RSpec.describe ActiveAdmin::Settings::Inheritance do subject do Class.new do diff --git a/spec/unit/view_factory_spec.rb b/spec/unit/view_factory_spec.rb index 06f605f3236..10378ca2310 100644 --- a/spec/unit/view_factory_spec.rb +++ b/spec/unit/view_factory_spec.rb @@ -6,7 +6,7 @@ def it_should_have_view(key, value) end end -describe ActiveAdmin::ViewFactory do +RSpec.describe ActiveAdmin::ViewFactory do it_should_have_view :global_navigation, ActiveAdmin::Views::TabbedNavigation it_should_have_view :utility_navigation, ActiveAdmin::Views::TabbedNavigation diff --git a/spec/unit/view_helpers/breadcrumbs_spec.rb b/spec/unit/view_helpers/breadcrumbs_spec.rb index 59660b9819a..21a1c4876c3 100644 --- a/spec/unit/view_helpers/breadcrumbs_spec.rb +++ b/spec/unit/view_helpers/breadcrumbs_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe "Breadcrumbs" do +RSpec.describe "Breadcrumbs" do include ActiveAdmin::ViewHelpers diff --git a/spec/unit/view_helpers/display_helper_spec.rb b/spec/unit/view_helpers/display_helper_spec.rb index d569233814e..fca2b16f61f 100644 --- a/spec/unit/view_helpers/display_helper_spec.rb +++ b/spec/unit/view_helpers/display_helper_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ViewHelpers::DisplayHelper do +RSpec.describe ActiveAdmin::ViewHelpers::DisplayHelper do include ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper include ActiveAdmin::ViewHelpers::AutoLinkHelper include ActiveAdmin::ViewHelpers::DisplayHelper diff --git a/spec/unit/view_helpers/download_format_links_helper_spec.rb b/spec/unit/view_helpers/download_format_links_helper_spec.rb index 0a761bc5c66..92dac35fccc 100644 --- a/spec/unit/view_helpers/download_format_links_helper_spec.rb +++ b/spec/unit/view_helpers/download_format_links_helper_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ViewHelpers::DownloadFormatLinksHelper do +RSpec.describe ActiveAdmin::ViewHelpers::DownloadFormatLinksHelper do describe "class methods" do before :all do begin diff --git a/spec/unit/view_helpers/fields_for_spec.rb b/spec/unit/view_helpers/fields_for_spec.rb index 3f1acd6310a..f531ef8ea7c 100644 --- a/spec/unit/view_helpers/fields_for_spec.rb +++ b/spec/unit/view_helpers/fields_for_spec.rb @@ -1,6 +1,6 @@ require 'active_admin/view_helpers/fields_for' -describe ActiveAdmin::ViewHelpers::FormHelper, ".fields_for" do +RSpec.describe ActiveAdmin::ViewHelpers::FormHelper, ".fields_for" do include ActiveAdmin::ViewHelpers::FormHelper it "should skip :action, :controller and :commit" do diff --git a/spec/unit/view_helpers/flash_helper_spec.rb b/spec/unit/view_helpers/flash_helper_spec.rb index 7d72802396e..c70f0dbbd04 100644 --- a/spec/unit/view_helpers/flash_helper_spec.rb +++ b/spec/unit/view_helpers/flash_helper_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ViewHelpers::FlashHelper do +RSpec.describe ActiveAdmin::ViewHelpers::FlashHelper do describe '.flash_messages' do let(:view) { action_view } diff --git a/spec/unit/view_helpers/form_helper_spec.rb b/spec/unit/view_helpers/form_helper_spec.rb index e97964ee9a4..e60f3936ee5 100644 --- a/spec/unit/view_helpers/form_helper_spec.rb +++ b/spec/unit/view_helpers/form_helper_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::ViewHelpers::FormHelper do +RSpec.describe ActiveAdmin::ViewHelpers::FormHelper do describe '.active_admin_form_for' do let(:view) { action_view } diff --git a/spec/unit/view_helpers/method_or_proc_helper_spec.rb b/spec/unit/view_helpers/method_or_proc_helper_spec.rb index 41a1e7de2a6..c50b2238a24 100644 --- a/spec/unit/view_helpers/method_or_proc_helper_spec.rb +++ b/spec/unit/view_helpers/method_or_proc_helper_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe MethodOrProcHelper do +RSpec.describe MethodOrProcHelper do let(:receiver) { double } let(:context) do diff --git a/spec/unit/views/components/attributes_table_spec.rb b/spec/unit/views/components/attributes_table_spec.rb index 0d393b994c0..93fb60f99f5 100644 --- a/spec/unit/views/components/attributes_table_spec.rb +++ b/spec/unit/views/components/attributes_table_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::AttributesTable do +RSpec.describe ActiveAdmin::Views::AttributesTable do describe "creating with the dsl" do let(:helpers) { action_view } diff --git a/spec/unit/views/components/batch_action_selector_spec.rb b/spec/unit/views/components/batch_action_selector_spec.rb index 9694ff72ee3..8cb6a3e1190 100644 --- a/spec/unit/views/components/batch_action_selector_spec.rb +++ b/spec/unit/views/components/batch_action_selector_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'active_admin/batch_actions/views/batch_action_selector' -describe ActiveAdmin::BatchActions::BatchActionSelector do +RSpec.describe ActiveAdmin::BatchActions::BatchActionSelector do let(:dropdown) do render_arbre_component do diff --git a/spec/unit/views/components/blank_slate_spec.rb b/spec/unit/views/components/blank_slate_spec.rb index 6bacd0b95ac..2d5ef848400 100644 --- a/spec/unit/views/components/blank_slate_spec.rb +++ b/spec/unit/views/components/blank_slate_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::BlankSlate do +RSpec.describe ActiveAdmin::Views::BlankSlate do describe "#blank_slate" do subject do diff --git a/spec/unit/views/components/columns_spec.rb b/spec/unit/views/components/columns_spec.rb index 41e8f016622..d76ed3888dd 100644 --- a/spec/unit/views/components/columns_spec.rb +++ b/spec/unit/views/components/columns_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::Columns do +RSpec.describe ActiveAdmin::Views::Columns do describe "Rendering zero columns" do let(:cols) do diff --git a/spec/unit/views/components/index_list_spec.rb b/spec/unit/views/components/index_list_spec.rb index d7e60cde142..b38590408dd 100644 --- a/spec/unit/views/components/index_list_spec.rb +++ b/spec/unit/views/components/index_list_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::IndexList do +RSpec.describe ActiveAdmin::Views::IndexList do describe "#index_list_renderer" do diff --git a/spec/unit/views/components/index_table_for_spec.rb b/spec/unit/views/components/index_table_for_spec.rb index 990772791bd..b929a729a48 100644 --- a/spec/unit/views/components/index_table_for_spec.rb +++ b/spec/unit/views/components/index_table_for_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::IndexAsTable::IndexTableFor do +RSpec.describe ActiveAdmin::Views::IndexAsTable::IndexTableFor do describe 'creating with the dsl' do let(:collection) do [Post.new(title: 'First Post', starred: true)] diff --git a/spec/unit/views/components/paginated_collection_spec.rb b/spec/unit/views/components/paginated_collection_spec.rb index 7c54f82e0cb..03a28babd39 100644 --- a/spec/unit/views/components/paginated_collection_spec.rb +++ b/spec/unit/views/components/paginated_collection_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::PaginatedCollection do +RSpec.describe ActiveAdmin::Views::PaginatedCollection do describe "creating with the dsl" do before :all do diff --git a/spec/unit/views/components/panel_spec.rb b/spec/unit/views/components/panel_spec.rb index a33fc5cb749..36e1926ee48 100644 --- a/spec/unit/views/components/panel_spec.rb +++ b/spec/unit/views/components/panel_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::Panel do +RSpec.describe ActiveAdmin::Views::Panel do let(:arbre_panel) do render_arbre_component do panel "My Title" do diff --git a/spec/unit/views/components/sidebar_section_spec.rb b/spec/unit/views/components/sidebar_section_spec.rb index 1f7a84ef2b9..5c31adb4865 100644 --- a/spec/unit/views/components/sidebar_section_spec.rb +++ b/spec/unit/views/components/sidebar_section_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::SidebarSection do +RSpec.describe ActiveAdmin::Views::SidebarSection do let(:options) { {} } diff --git a/spec/unit/views/components/site_title_spec.rb b/spec/unit/views/components/site_title_spec.rb index fef2d0fd3cd..709617866ba 100644 --- a/spec/unit/views/components/site_title_spec.rb +++ b/spec/unit/views/components/site_title_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::SiteTitle do +RSpec.describe ActiveAdmin::Views::SiteTitle do let(:helpers){ mock_action_view } diff --git a/spec/unit/views/components/status_tag_spec.rb b/spec/unit/views/components/status_tag_spec.rb index 7dba5da93cf..3485ff21fe1 100644 --- a/spec/unit/views/components/status_tag_spec.rb +++ b/spec/unit/views/components/status_tag_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::StatusTag do +RSpec.describe ActiveAdmin::Views::StatusTag do describe "#status_tag" do diff --git a/spec/unit/views/components/table_for_spec.rb b/spec/unit/views/components/table_for_spec.rb index d1cabfaf688..59d6bc923c6 100644 --- a/spec/unit/views/components/table_for_spec.rb +++ b/spec/unit/views/components/table_for_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::TableFor do +RSpec.describe ActiveAdmin::Views::TableFor do describe "creating with the dsl" do let(:collection) do diff --git a/spec/unit/views/components/tabs_spec.rb b/spec/unit/views/components/tabs_spec.rb index 8329412ca66..9adc1bc99fb 100644 --- a/spec/unit/views/components/tabs_spec.rb +++ b/spec/unit/views/components/tabs_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::Tabs do +RSpec.describe ActiveAdmin::Views::Tabs do describe "creating with the dsl" do context "when creating tabs with a symbol" do let(:tabs) do diff --git a/spec/unit/views/components/unsupported_browser_spec.rb b/spec/unit/views/components/unsupported_browser_spec.rb index 1af3c129d2d..c636093b9fd 100644 --- a/spec/unit/views/components/unsupported_browser_spec.rb +++ b/spec/unit/views/components/unsupported_browser_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::UnsupportedBrowser do +RSpec.describe ActiveAdmin::Views::UnsupportedBrowser do let(:helpers){ mock_action_view } let(:namespace) { double :namespace, unsupported_browser_matcher: /MSIE [1-8]\.0/ } let(:component) { double :unsupported_browser_component } diff --git a/spec/unit/views/index_as_blog_spec.rb b/spec/unit/views/index_as_blog_spec.rb index 6a001f6397c..0fe267b939b 100644 --- a/spec/unit/views/index_as_blog_spec.rb +++ b/spec/unit/views/index_as_blog_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' include ActiveAdmin -describe ActiveAdmin::Views::IndexAsBlog do +RSpec.describe ActiveAdmin::Views::IndexAsBlog do subject { described_class.new } describe '#build' do diff --git a/spec/unit/views/pages/form_spec.rb b/spec/unit/views/pages/form_spec.rb index 57c4cdc48fe..95d39fa83c8 100644 --- a/spec/unit/views/pages/form_spec.rb +++ b/spec/unit/views/pages/form_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::Pages::Form do +RSpec.describe ActiveAdmin::Views::Pages::Form do describe "#title" do let!(:application){ ActiveAdmin::Application.new } let(:namespace){ ActiveAdmin::Namespace.new(application, "Admin") } diff --git a/spec/unit/views/pages/index_spec.rb b/spec/unit/views/pages/index_spec.rb index 041344ae545..d83abba964c 100644 --- a/spec/unit/views/pages/index_spec.rb +++ b/spec/unit/views/pages/index_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::Pages::Index do +RSpec.describe ActiveAdmin::Views::Pages::Index do describe "#title" do let!(:application){ ActiveAdmin::Application.new } let(:namespace){ ActiveAdmin::Namespace.new(application, "Admin") } diff --git a/spec/unit/views/pages/layout_spec.rb b/spec/unit/views/pages/layout_spec.rb index 1b742d61a2e..3dfa274a0da 100644 --- a/spec/unit/views/pages/layout_spec.rb +++ b/spec/unit/views/pages/layout_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::Pages::Layout do +RSpec.describe ActiveAdmin::Views::Pages::Layout do let(:assigns){ {} } let(:helpers) do diff --git a/spec/unit/views/pages/show_spec.rb b/spec/unit/views/pages/show_spec.rb index a55ba118eb7..bc5945d1cbe 100644 --- a/spec/unit/views/pages/show_spec.rb +++ b/spec/unit/views/pages/show_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe ActiveAdmin::Views::Pages::Show do +RSpec.describe ActiveAdmin::Views::Pages::Show do describe "the resource" do let(:helpers) { double resource: resource } diff --git a/spec/unit/views/tabbed_navigation_spec.rb b/spec/unit/views/tabbed_navigation_spec.rb index e52556fbd08..355750284ac 100644 --- a/spec/unit/views/tabbed_navigation_spec.rb +++ b/spec/unit/views/tabbed_navigation_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' include ActiveAdmin -describe ActiveAdmin::Views::TabbedNavigation do +RSpec.describe ActiveAdmin::Views::TabbedNavigation do let(:menu){ ActiveAdmin::Menu.new } From f2d96008ffae6447a8436fd6933ccc42aa6367b1 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sat, 18 Feb 2017 17:20:33 +0200 Subject: [PATCH 0307/3836] fixes #4803, improve filters specs --- spec/support/rails_template.rb | 12 ++++++++++++ spec/unit/filters/filter_form_builder_spec.rb | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index c08b0aa86a9..b4fba8d644e 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -14,6 +14,18 @@ class Post < ActiveRecord::Base accepts_nested_attributes_for :author accepts_nested_attributes_for :taggings + ransacker :custom_title_searcher do |parent| + parent.table[:title] + end + + ransacker :custom_created_at_searcher do |parent| + parent.table[:created_at] + end + + ransacker :custom_searcher_numeric, type: :numeric do + # nothing to see here + end + unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes attr_accessible :id, :title, :body, :starred, :author, :position, :published_date, :author_id, :custom_category_id, :category end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index f14d5d85da8..06897954be5 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -1,17 +1,5 @@ require 'rails_helper' -class Post - ransacker :custom_title_searcher do |parent| - parent.table[:title] - end - ransacker :custom_created_at_searcher do |parent| - parent.table[:created_at] - end - ransacker :custom_searcher_numeric, type: :numeric do - # nothing to see here - end -end - RSpec.describe ActiveAdmin::Filters::ViewHelper do # Setup an ActionView::Base object which can be used for From aa66ec4fe70aa6395022c83925c7a815a7f6c134 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sun, 19 Feb 2017 00:43:49 +0200 Subject: [PATCH 0308/3836] search options overriding for numeric and string filters (specs and docs) [closes #4800] --- docs/3-index-pages.md | 6 ++ spec/unit/filters/filter_form_builder_spec.rb | 60 ++++++++++++++----- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index f0effecc4db..6635dcadb22 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -100,6 +100,12 @@ the collection as a proc to be called at render time. filter :author, as: :check_boxes, collection: proc { Author.all } ``` +To override options for string or numeric filter pass `filters` option. + +```ruby + filter :title, filters: [:starts_with, :ends_with] +``` + Also, if you don't need the select with the options 'contains', 'equals', 'starts_with' or 'ends_with' just add the option to the filter name with an underscore. diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 06897954be5..d5f3f9bb659 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -96,6 +96,19 @@ def filter(name, options = {}) expect(body).to have_selector("option[value=title_starts_with][selected=selected]", text: "Starts with") end + context "with filters options" do + let(:body) { Capybara.string(filter :title, filters: [:contains, :starts_with]) } + + it "should generate provided options for filter select" do + expect(body).to have_selector("option[value=title_contains]", text: "Contains") + expect(body).to have_selector("option[value=title_starts_with]", text: "Starts with") + end + + it "should not generate a select option for ends with" do + expect(body).not_to have_selector("option[value=title_ends_with]") + end + end + context "with predicate" do %w[eq equals cont contains start starts_with end ends_with].each do |predicate| describe "'#{predicate}'" do @@ -176,24 +189,39 @@ def filter(name, options = {}) end describe "integer attribute" do - let(:body) { Capybara.string(filter :id) } + context "without options" do + let(:body) { Capybara.string(filter :id) } - it "should generate a select option for equal to" do - expect(body).to have_selector("option[value=id_equals]", text: "Equals") - end - it "should generate a select option for greater than" do - expect(body).to have_selector("option", text: "Greater than") - end - it "should generate a select option for less than" do - expect(body).to have_selector("option", text: "Less than") - end - it "should generate a text field for input" do - expect(body).to have_selector("input[name='q[id_equals]']") + it "should generate a select option for equal to" do + expect(body).to have_selector("option[value=id_equals]", text: "Equals") + end + it "should generate a select option for greater than" do + expect(body).to have_selector("option[value=id_greater_than]", text: "Greater than") + end + it "should generate a select option for less than" do + expect(body).to have_selector("option[value=id_less_than]", text: "Less than") + end + it "should generate a text field for input" do + expect(body).to have_selector("input[name='q[id_equals]']") + end + it "should select the option which is currently being filtered" do + scope = Post.search id_greater_than: 1 + body = Capybara.string(render_filter scope, id: {}) + expect(body).to have_selector("option[value=id_greater_than][selected=selected]", text: "Greater than") + end end - it "should select the option which is currently being filtered" do - scope = Post.search id_greater_than: 1 - body = Capybara.string(render_filter scope, id: {}) - expect(body).to have_selector("option[value=id_greater_than][selected=selected]", text: "Greater than") + + context "with filters options" do + let(:body) { Capybara.string(filter :id, filters: [:equals, :greater_than]) } + + it "should generate provided options for filter select" do + expect(body).to have_selector("option[value=id_equals]", text: "Equals") + expect(body).to have_selector("option[value=id_greater_than]", text: "Greater than") + end + + it "should not generate a select option for less than" do + expect(body).not_to have_selector("option[value=id_less_than]") + end end end From ec30b8340db562b7a1527a2d8b5b60eaa0f41ab3 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Sat, 25 Oct 2014 09:17:05 -0400 Subject: [PATCH 0309/3836] Landing page and assets scraped from old site. --- docs/documentation.html | 224 +++++++ docs/images/activeadmin.png | Bin 0 -> 4387 bytes docs/images/code-header.png | Bin 0 -> 1932 bytes docs/images/divider.png | Bin 0 -> 113 bytes docs/images/features.png | Bin 0 -> 143602 bytes docs/index.html | 119 ++++ docs/stylesheets/main.css | 1199 +++++++++++++++++++++++++++++++++++ 7 files changed, 1542 insertions(+) create mode 100644 docs/documentation.html create mode 100644 docs/images/activeadmin.png create mode 100644 docs/images/code-header.png create mode 100644 docs/images/divider.png create mode 100644 docs/images/features.png create mode 100644 docs/index.html create mode 100644 docs/stylesheets/main.css diff --git a/docs/documentation.html b/docs/documentation.html new file mode 100644 index 00000000000..20afd6d665b --- /dev/null +++ b/docs/documentation.html @@ -0,0 +1,224 @@ + + + + + + Active Admin | The administration framework for Ruby on Rails + + + + + + + + + + +
      + + + +
      + + +
      +

      + + Documentation : + + + + Active Admin Documentation +

      + +
      +

      Active Admin is a framework for creating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort.

      + +

      Getting Started

      + +

      Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails 3 application. To install, simply add the following to your Gemfile:

      +
        # Gemfile
      +  gem 'activeadmin'
      +
      +
      +

      If you are using Rails >= 3.1, you must also include a beta version of MetaSearch and sass-rails:

      +
        # Gemfile in Rails >= 3.1
      +  gem 'activeadmin'
      +  gem 'sass-rails'
      +  gem "meta_search",    '>= 1.1.0.pre'
      +
      +
      +

      After updating your bundle, run the installer

      +
        $> rails generate active_admin:install
      +
      +
      +

      The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at app/admin to put all your admin configurations.

      + +

      Migrate your db and start the server:

      +
        $> rake db:migrate
      +  $> rails server
      +
      +
      +

      Visit http://localhost:3000/admin and log in using:

      + +
        +
      • User: admin@example.com
      • + +
      • Password: password
      • +
      + +

      Voila! You’re on your brand new Active Admin dashboard.

      + +

      To register your first model, run:

      +
        $> rails generate active_admin:resource [MyModelName]
      +
      +
      +

      This creates a file at app/admin/my_model_names.rb for configuring the resource. Refresh your web browser to see the interface.

      + +

      Next Steps

      + +

      Now that you have a working Active Admin installation, learn how to customize it:

      + + +
      + +
      + +
      + +
      + Copyright 2011 Greg Bell and VersaPay +
      +
      +

      +
      +

      + +
      + + + + + + + diff --git a/docs/images/activeadmin.png b/docs/images/activeadmin.png new file mode 100644 index 0000000000000000000000000000000000000000..a2890603239ac4d0510c0b59d00c0fcb4938d198 GIT binary patch literal 4387 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 literal 0 HcmV?d00001 diff --git a/docs/images/code-header.png b/docs/images/code-header.png new file mode 100644 index 0000000000000000000000000000000000000000..f94e9cac2406fa0a6762fb08b603b52f6164ec61 GIT binary patch literal 1932 zcmV;72Xpv|P)+AnxN=YeV}kJAc^BhaTCXN z8eg)dIN~LeyUX33otX|viKQ-Emt{o#eF&~r%iqop=lcGB!yOWzKl|r=zM$zkLW*dD zR-b6?wz-D@00000c;qOn&(>!34_bM&Kqw5uY^EC*ip9yPsh*x*O6i7_n&)mu=T{6{ z)(`Lql(w;GJ^%m!004LhV2pjge(C*-cxfqr@~h9~^Z8C^K~Yr&W9s{?=>cFuuwn2h z5}a?4cm-iyzQp~y5M0%C)v^?+_ne8fsxLKOl@CP?!g|D*+#|Y)H5_reI(YybUJq1J z{@?3ZHhonUjefD?qHC5OKj89f=2!M(4qX%aCh(;uolaM)HC%IQk(BBV6_?dscirpn zy?f`KcbHp4LLuGVW8XSG`t;LAW43<{l=J0(e^UPY1$OtArYKA&=CR|M=U+%Ekbdw)oMRi*Nt> zuOIy2<=?CbWl1!>j3}&01is*S;R2sB5Kk)su40jJLjG|^SwlDQehdV z%ABgLE4@U0?@xcsPEHO@PqU`6s%cKSB6w} z{Z}=_1?N)fk)r(b^7$Ly?DR8(**=q4+_IJNqrJDxyJu$K9L|kpy0Z-8h{Fp^6#@VN zgUKVIF?lceN@U*_S{73GgZEFG`s1b=Teykd{0(MNwz~XO-0+;BJUiPrHPxEkE0mXUX-*h_~gQ_N2$6J4n|CIn$! z5JGfa3xda3Jp|D*j)cKV17nHUP`{B*Xojw+f~UG7*W}pfE8nh!9%FV(>;vkX zy<+spU@B>0Rl%ytc`W1x<=mN~b+^VM{;(r^m`Mfz;DCW)2YBSPKB>p@Nhxhl;|o=g zuC%EM(%;WhHnQ!;dc8{7sw|sgQBNi*4N=Qj4HcbeY1_)Bane#O6KSeOBh3mJM<`X1 zTR|hlBemfLh_1Muvf{QClTJho8iaxOnkkD~GTDel(Cc8>0s!bW@Qz@>+26>X zGmb?gQ2$?K-&k-nbF^~xqoJW;lmAd>6jKOUSgb+xQHlfEZ5_@W@O1Qb;@=wnNZC*u_&XO>Xv**c%-*$B%lEo z4Eibn001}#!2XK8tOd-)nj7?_G?U}Umul6%L@LuafKsW(nmC<&?s&_SQ+RSB^8FP{ zN;P|=>dh=HERNM5g{p78s3$%xt-L|d}RZ|U( z=I1Lt`b6634MHCp1ONa40PKHcFE&K>QuzfT`q#hl>D~Fkx}TI1E>Oj*FIX`&b5us( zO2>-)DD>3+Z_ZaP(JO`AfJF@K)abo=zhs^YtdS`2+WIXomLQq&__r5s%!bu_@t74x zQK94zZ*<5$;d^xiLJt4{008@q)OW!JZtZp69LIvdF%0$Cmv1f-HTg2Df7i@`Ht(-C_*;RBxAX1 zr6LeVp!NU&JW^my7ZmlO6?-JbzB!G*?oRl?^9sIi*|v)t-T)25dbunu)y7@)d~JnA z<#NF=?T`$VxXP`__i9m8*>q06=2UPUCt^o%s3XLs{1<~l``bXFN&o-=1pN63GD%DbFvYTEV007{Cfq@7( zl(d8!BaSEyH~Gms000000KVij7R<}Y-f`Wt=l>D}LF2Cb{rcRzom9(FRW#b5z-B_un`QZNKQ&rHLMt=j{xh zyKB8$wFGqEdPiFr?4sT7qV%?EsAwmHu=1eN-pk;;Q@z_uxglg2M%{J(E5HC%)-+Wc SZm~E30000DSr z1<%~X^wgl##FWaylc_d9MZ%sgjv*Ddk}7_FkvshV|9?g%9tJT{)>W>aK_H_TJYD@< J);T3K0RZK)9`yhK literal 0 HcmV?d00001 diff --git a/docs/images/features.png b/docs/images/features.png new file mode 100644 index 0000000000000000000000000000000000000000..e5a5c753bf15384858efa94ed06e6c2f60d115ca GIT binary patch literal 143602 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 literal 0 HcmV?d00001 diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000000..3c2f6744436 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,119 @@ + + + + + + Active Admin | The administration framework for Ruby on Rails + + + + + + + + + + + + + + + + + + diff --git a/docs/stylesheets/main.css b/docs/stylesheets/main.css new file mode 100644 index 00000000000..881367bc597 --- /dev/null +++ b/docs/stylesheets/main.css @@ -0,0 +1,1199 @@ +/* line 17, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +/* line 20, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +body { + line-height: 1; +} + +/* line 22, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +ol, ul { + list-style: none; +} + +/* line 24, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +table { + border-collapse: collapse; + border-spacing: 0; +} + +/* line 26, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +caption, th, td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} + +/* line 28, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +q, blockquote { + quotes: none; +} +/* line 101, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +q:before, q:after, blockquote:before, blockquote:after { + content: ""; + content: none; +} + +/* line 30, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +a img { + border: none; +} + +/* line 115, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} + +/* line 1, ../_sass/_highlight.scss */ +#dsl { + /* Comment */ + /* Error */ + /* Keyword */ + /* Literal */ + /* Name */ + /* Operator */ + /* Punctuation */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Emph */ + /* Generic.Strong */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Namespace */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Date */ + /* Literal.Number */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Decorator */ + /* Name.Entity */ + /* Name.Exception */ + /* Name.Function */ + /* Name.Label */ + /* Name.Namespace */ + /* Name.Other */ + /* Name.Property */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Literal.Number.Integer.Long */ +} +/* line 2, ../_sass/_highlight.scss */ +#dsl .highlight .hll { + background-color: #49483e; +} +/* line 3, ../_sass/_highlight.scss */ +#dsl .highlight { + background: #272822; + color: #f8f8f2; +} +/* line 4, ../_sass/_highlight.scss */ +#dsl .highlight .c { + color: #75715e; +} +/* line 5, ../_sass/_highlight.scss */ +#dsl .highlight .err { + color: #960050; + background-color: #1e0010; +} +/* line 6, ../_sass/_highlight.scss */ +#dsl .highlight .k { + color: #66d9ef; +} +/* line 7, ../_sass/_highlight.scss */ +#dsl .highlight .l { + color: #ae81ff; +} +/* line 8, ../_sass/_highlight.scss */ +#dsl .highlight .n { + color: #f8f8f2; +} +/* line 9, ../_sass/_highlight.scss */ +#dsl .highlight .o { + color: #f92672; +} +/* line 10, ../_sass/_highlight.scss */ +#dsl .highlight .p { + color: #f8f8f2; +} +/* line 11, ../_sass/_highlight.scss */ +#dsl .highlight .cm { + color: #75715e; +} +/* line 12, ../_sass/_highlight.scss */ +#dsl .highlight .cp { + color: #75715e; +} +/* line 13, ../_sass/_highlight.scss */ +#dsl .highlight .c1 { + color: #75715e; +} +/* line 14, ../_sass/_highlight.scss */ +#dsl .highlight .cs { + color: #75715e; +} +/* line 15, ../_sass/_highlight.scss */ +#dsl .highlight .ge { + font-style: italic; +} +/* line 16, ../_sass/_highlight.scss */ +#dsl .highlight .gs { + font-weight: bold; +} +/* line 17, ../_sass/_highlight.scss */ +#dsl .highlight .kc { + color: #66d9ef; +} +/* line 18, ../_sass/_highlight.scss */ +#dsl .highlight .kd { + color: #66d9ef; +} +/* line 19, ../_sass/_highlight.scss */ +#dsl .highlight .kn { + color: #f92672; +} +/* line 20, ../_sass/_highlight.scss */ +#dsl .highlight .kp { + color: #66d9ef; +} +/* line 21, ../_sass/_highlight.scss */ +#dsl .highlight .kr { + color: #66d9ef; +} +/* line 22, ../_sass/_highlight.scss */ +#dsl .highlight .kt { + color: #66d9ef; +} +/* line 23, ../_sass/_highlight.scss */ +#dsl .highlight .ld { + color: #e6db74; +} +/* line 24, ../_sass/_highlight.scss */ +#dsl .highlight .m { + color: #ae81ff; +} +/* line 25, ../_sass/_highlight.scss */ +#dsl .highlight .s { + color: #e6db74; +} +/* line 26, ../_sass/_highlight.scss */ +#dsl .highlight .na { + color: #a6e22e; +} +/* line 27, ../_sass/_highlight.scss */ +#dsl .highlight .nb { + color: #f8f8f2; +} +/* line 28, ../_sass/_highlight.scss */ +#dsl .highlight .nc { + color: #a6e22e; +} +/* line 29, ../_sass/_highlight.scss */ +#dsl .highlight .no { + color: #66d9ef; +} +/* line 30, ../_sass/_highlight.scss */ +#dsl .highlight .nd { + color: #a6e22e; +} +/* line 31, ../_sass/_highlight.scss */ +#dsl .highlight .ni { + color: #f8f8f2; +} +/* line 32, ../_sass/_highlight.scss */ +#dsl .highlight .ne { + color: #a6e22e; +} +/* line 33, ../_sass/_highlight.scss */ +#dsl .highlight .nf { + color: #a6e22e; +} +/* line 34, ../_sass/_highlight.scss */ +#dsl .highlight .nl { + color: #f8f8f2; +} +/* line 35, ../_sass/_highlight.scss */ +#dsl .highlight .nn { + color: #f8f8f2; +} +/* line 36, ../_sass/_highlight.scss */ +#dsl .highlight .nx { + color: #a6e22e; +} +/* line 37, ../_sass/_highlight.scss */ +#dsl .highlight .py { + color: #f8f8f2; +} +/* line 38, ../_sass/_highlight.scss */ +#dsl .highlight .nt { + color: #f92672; +} +/* line 39, ../_sass/_highlight.scss */ +#dsl .highlight .nv { + color: #f8f8f2; +} +/* line 40, ../_sass/_highlight.scss */ +#dsl .highlight .ow { + color: #f92672; +} +/* line 41, ../_sass/_highlight.scss */ +#dsl .highlight .w { + color: #f8f8f2; +} +/* line 42, ../_sass/_highlight.scss */ +#dsl .highlight .mf { + color: #ae81ff; +} +/* line 43, ../_sass/_highlight.scss */ +#dsl .highlight .mh { + color: #ae81ff; +} +/* line 44, ../_sass/_highlight.scss */ +#dsl .highlight .mi { + color: #ae81ff; +} +/* line 45, ../_sass/_highlight.scss */ +#dsl .highlight .mo { + color: #ae81ff; +} +/* line 46, ../_sass/_highlight.scss */ +#dsl .highlight .sb { + color: #e6db74; +} +/* line 47, ../_sass/_highlight.scss */ +#dsl .highlight .sc { + color: #e6db74; +} +/* line 48, ../_sass/_highlight.scss */ +#dsl .highlight .sd { + color: #e6db74; +} +/* line 49, ../_sass/_highlight.scss */ +#dsl .highlight .s2 { + color: #e6db74; +} +/* line 50, ../_sass/_highlight.scss */ +#dsl .highlight .se { + color: #ae81ff; +} +/* line 51, ../_sass/_highlight.scss */ +#dsl .highlight .sh { + color: #e6db74; +} +/* line 52, ../_sass/_highlight.scss */ +#dsl .highlight .si { + color: #e6db74; +} +/* line 53, ../_sass/_highlight.scss */ +#dsl .highlight .sx { + color: #e6db74; +} +/* line 54, ../_sass/_highlight.scss */ +#dsl .highlight .sr { + color: #e6db74; +} +/* line 55, ../_sass/_highlight.scss */ +#dsl .highlight .s1 { + color: #e6db74; +} +/* line 56, ../_sass/_highlight.scss */ +#dsl .highlight .ss { + color: #AE81FF; +} +/* line 57, ../_sass/_highlight.scss */ +#dsl .highlight .bp { + color: #f8f8f2; +} +/* line 58, ../_sass/_highlight.scss */ +#dsl .highlight .vc { + color: #f8f8f2; +} +/* line 59, ../_sass/_highlight.scss */ +#dsl .highlight .vg { + color: #f8f8f2; +} +/* line 60, ../_sass/_highlight.scss */ +#dsl .highlight .vi { + color: #f8f8f2; +} +/* line 61, ../_sass/_highlight.scss */ +#dsl .highlight .il { + color: #ae81ff; +} + +/* line 33, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +body { + line-height: 1.5; + font-family: "Helvetica Neue", Arial, Helvetica, sans-serif; + color: #333333; + font-size: 75%; +} + +/* line 51, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h1, h2, h3, h4, h5, h6 { + font-weight: normal; + color: #222222; +} +/* line 52, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h1 img, h2 img, h3 img, h4 img, h5 img, h6 img { + margin: 0; +} + +/* line 53, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h1 { + font-size: 3em; + line-height: 1; + margin-bottom: 0.50em; +} + +/* line 54, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h2 { + font-size: 2em; + margin-bottom: 0.75em; +} + +/* line 55, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h3 { + font-size: 1.5em; + line-height: 1; + margin-bottom: 1.00em; +} + +/* line 56, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h4 { + font-size: 1.2em; + line-height: 1.25; + margin-bottom: 1.25em; +} + +/* line 57, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h5 { + font-size: 1em; + font-weight: bold; + margin-bottom: 1.50em; +} + +/* line 58, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +h6 { + font-size: 1em; + font-weight: bold; +} + +/* line 59, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +p { + margin: 0 0 1.5em; +} +/* line 60, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +p .left { + display: inline; + float: left; + margin: 1.5em 1.5em 1.5em 0; + padding: 0; +} +/* line 61, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +p .right { + display: inline; + float: right; + margin: 1.5em 0 1.5em 1.5em; + padding: 0; +} + +/* line 62, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +a { + text-decoration: underline; + color: #0066cc; +} +/* line 18, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */ +a:visited { + color: #004c99; +} +/* line 21, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */ +a:focus { + color: #0099ff; +} +/* line 24, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */ +a:hover { + color: #0099ff; +} +/* line 27, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */ +a:active { + color: #bf00ff; +} + +/* line 63, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +blockquote { + margin: 1.5em; + color: #666666; + font-style: italic; +} + +/* line 64, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +strong, dfn { + font-weight: bold; +} + +/* line 65, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +em, dfn { + font-style: italic; +} + +/* line 66, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +sup, sub { + line-height: 0; +} + +/* line 67, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +abbr, acronym { + border-bottom: 1px dotted #666666; +} + +/* line 68, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +address { + margin: 0 0 1.5em; + font-style: italic; +} + +/* line 69, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +del { + color: #666666; +} + +/* line 70, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +pre { + margin: 1.5em 0; + white-space: pre; +} + +/* line 71, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +pre, code, tt { + font: 1em "andale mono", "lucida console", monospace; + line-height: 1.5; +} + +/* line 72, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +li ul, li ol { + margin: 0; +} + +/* line 73, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +ul, ol { + margin: 0 1.5em 1.5em 0; + padding-left: 1.5em; +} + +/* line 74, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +ul { + list-style-type: disc; +} + +/* line 75, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +ol { + list-style-type: decimal; +} + +/* line 76, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +dl { + margin: 0 0 1.5em 0; +} +/* line 77, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +dl dt { + font-weight: bold; +} + +/* line 78, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +dd { + margin-left: 1.5em; +} + +/* line 79, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +table { + margin-bottom: 1.4em; + width: 100%; +} + +/* line 80, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +th { + font-weight: bold; +} + +/* line 81, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +thead th { + background: #c3d9ff; +} + +/* line 82, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +th, td, caption { + padding: 4px 10px 4px 5px; +} + +/* line 85, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +table.striped tr:nth-child(even) td, +table tr.even td { + background: #e5ecf9; +} + +/* line 86, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +tfoot { + font-style: italic; +} + +/* line 87, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +caption { + background: #eeeeee; +} + +/* line 88, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +.quiet { + color: #666666; +} + +/* line 89, ../../../../.rvm/gems/ruby-1.9.2-p136/gems/compass-0.11.1/frameworks/blueprint/stylesheets/blueprint/_typography.scss */ +.loud { + color: #111111; +} + +/* line 11, ../_sass/main.scss */ +body { + background: #f6f4f1; + color: #676767; + width: 676px; + padding: 0 20px; + font-size: 95%; + margin: 25px auto; + font-family: 'Georgia'; +} +/* line 20, ../_sass/main.scss */ +body #wrapper { + position: relative; +} +/* line 22, ../_sass/main.scss */ +body a, body a:hover, body a:link, body a:visited { + color: #407985; +} +/* line 26, ../_sass/main.scss */ +body h1, body h2, body h3, body h4, body h5, body h6 { + color: #595959; + font-family: 'Yanone Kaffeesatz', 'Helvetica Neue', Arial, Helvetica, sans-serif; +} +/* line 31, ../_sass/main.scss */ +body h1 a { + background: url("../images/activeadmin.png") 0 0 no-repeat; + display: block; + width: 257px; + height: 55px; +} +/* line 36, ../_sass/main.scss */ +body h1 a span { + display: none; +} +/* line 39, ../_sass/main.scss */ +body #header { + margin: 40px 0; +} +/* line 43, ../_sass/main.scss */ +body .clear { + clear: both; +} +/* line 45, ../_sass/main.scss */ +body .intro { + color: #595959; + font-family: 'Yanone Kaffeesatz', 'Helvetica Neue', Arial, Helvetica, sans-serif; + font-size: 3.2em; + font-weight: 300; + line-height: 1em; + margin-bottom: 0.3em; + padding-top: 35px; + background: url("../images/divider.png") 0 0 repeat-x; +} +/* line 52, ../_sass/main.scss */ +body .intro strong { + font-weight: 400; +} +/* line 57, ../_sass/main.scss */ +body h2 { + margin: 50px 0 10px 0; + padding-top: 35px; + background: url("../images/divider.png") 0 0 repeat-x; + font-size: 2.5em; + font-weight: 200; + line-height: 105%; +} +/* line 66, ../_sass/main.scss */ +body h3 { + margin-top: 30px; + margin-bottom: 10px; + font-size: 1.7em; + font-weight: 300; +} +/* line 73, ../_sass/main.scss */ +body #nav { + font-family: 'Yanone Kaffeesatz', 'Helvetica Neue', Arial, Helvetica, sans-serif; + font-weight: 400; + font-size: 1.2em; + text-transform: uppercase; + position: absolute; + right: 0; + top: 20px; + text-align: right; +} +/* line 82, ../_sass/main.scss */ +body #nav a { + text-decoration: none; + color: #8b9091; + margin-left: 20px; +} +/* line 90, ../_sass/main.scss */ +body #features { + padding-top: 0; + clear: both; + background: url("../images/features.png") 0 0 no-repeat; + margin: 0 -35px; + overflow: visible; + min-height: 569px; + font-size: 1.0em; + line-height: 1.2em; + font-weight: 300; + font-family: 'Yanone Kaffeesatz', 'Helvetica Neue', Arial, Helvetica, sans-serif; +} +/* line 103, ../_sass/main.scss */ +body #features #features-left { + float: left; + width: 150px; + margin-left: -150px; +} +/* line 104, ../_sass/main.scss */ +body #features #features-right { + float: right; + width: 150px; + margin-right: -150px; +} +/* line 106, ../_sass/main.scss */ +body #features h3 { + font-size: 1.2em; + padding-bottom: 0; + margin-bottom: 5px; +} +/* line 110, ../_sass/main.scss */ +body #features h3.first { + margin-top: 10px; +} +/* line 115, ../_sass/main.scss */ +body.with-sidebar { + width: 976px; +} +/* line 117, ../_sass/main.scss */ +body .toc { + font-family: Helvetica, Arial, sans-serif; + padding-top: 35px; + width: 270px; + float: right; + font-size: 0.9em; + background: url("../images/divider.png") top left repeat-x; +} +/* line 124, ../_sass/main.scss */ +body .toc ol li { + list-style: none; +} +/* line 127, ../_sass/main.scss */ +body .toc a, body .toc a:link, body .toc a:hover, body .toc a:visited { + text-decoration: none; + color: #595959; +} +/* line 128, ../_sass/main.scss */ +body .toc ol.level-1 > li { + font-size: 1.0em; + font-weight: bold; + margin-top: 20px; +} +/* line 133, ../_sass/main.scss */ +body .toc ol.level-1 > ol { + padding-left: 0; + font-size: 0.95em; + margin: 0; +} +/* line 134, ../_sass/main.scss */ +body .toc ol.level-2 > ol { + display: none; +} +/* line 136, ../_sass/main.scss */ +body .toc-content { + width: 676px; +} +/* line 138, ../_sass/main.scss */ +body #dsl { + margin-top: 20px; +} +/* line 140, ../_sass/main.scss */ +body #dsl .highlight { + font-size: 0.82em; + background: #292929 url("../images/code-header.png") 0 0 no-repeat; + padding: 40px 15px 20px 15px !important; + -moz-box-shadow: 0 8px 20px #444444; + -webkit-box-shadow: 0 8px 20px #444444; + -o-box-shadow: 0 8px 20px #444444; + box-shadow: 0 8px 20px #444444; +} +/* line 148, ../_sass/main.scss */ +body .getting-started { + font-size: 2em; + text-align: center; +} +/* line 151, ../_sass/main.scss */ +body .getting-started a { + margin-right: 15px; + display: block; +} +/* line 154, ../_sass/main.scss */ +body .getting-started-heading { + text-align: center; +} +/* line 156, ../_sass/main.scss */ +body .left { + float: left; +} +/* line 157, ../_sass/main.scss */ +body .right { + float: right; +} +/* line 159, ../_sass/main.scss */ +body .highlight { + background-color: #333; + font-family: "Droid Sans Mono", Monaco, monospace; + padding: 10px 5px; + font-size: 0.9em; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; + margin-bottom: 1.5em; +} +/* line 165, ../_sass/main.scss */ +body .highlight > pre, body .highlight code, body .highlight span { + line-height: 1.3em; + margin: 0; + padding: 0; +} +/* line 169, ../_sass/main.scss */ +body #footer { + margin-top: 50px; + margin-bottom: 20px; + background: url("../images/divider.png") 0 0 repeat-x; + clear: both; + padding-top: 20px; + font-size: 0.9em; +} +/* line 179, ../_sass/main.scss */ +body .post .post-date, body .post .post-meta { + font-size: 0.7em; +} +/* line 180, ../_sass/main.scss */ +body .post .post-date { + display: inline-block; + width: 100px; +} +/* line 181, ../_sass/main.scss */ +body .post .post-meta { + font-size: 0.6em; + padding-left: 40px; +} + +/* line 185, ../_sass/main.scss */ +span.breadcrumb { + display: block; + font-size: 45%; + font-weight: 200; + margin: 0; + padding: 0; +} + +/* line 193, ../_sass/main.scss */ +h2.in-docs { + font-weight: 400; +} + +/* line 198, ../_sass/main.scss */ +.docs-content { + /* Comment */ + /* Error */ + /* Keyword */ + /* Comment.Multiline */ + /* Comment.Preproc */ + /* Comment.Single */ + /* Comment.Special */ + /* Generic.Deleted */ + /* Generic.Emph */ + /* Generic.Error */ + /* Generic.Heading */ + /* Generic.Inserted */ + /* Generic.Output */ + /* Generic.Prompt */ + /* Generic.Strong */ + /* Generic.Subheading */ + /* Generic.Traceback */ + /* Keyword.Constant */ + /* Keyword.Declaration */ + /* Keyword.Namespace */ + /* Keyword.Pseudo */ + /* Keyword.Reserved */ + /* Keyword.Type */ + /* Literal.Number */ + /* Name */ + /* Name */ + /* Literal.String */ + /* Name.Attribute */ + /* Name.Builtin */ + /* Name.Class */ + /* Name.Constant */ + /* Name.Decorator */ + /* Name.Entity */ + /* Name.Function */ + /* Name.Namespace */ + /* Name.Tag */ + /* Name.Variable */ + /* Operator.Word */ + /* Text.Whitespace */ + /* Literal.Number.Float */ + /* Literal.Number.Hex */ + /* Literal.Number.Integer */ + /* Literal.Number.Oct */ + /* Literal.String.Backtick */ + /* Literal.String.Char */ + /* Literal.String.Doc */ + /* Literal.String.Double */ + /* Literal.String.Escape */ + /* Literal.String.Heredoc */ + /* Literal.String.Interpol */ + /* Literal.String.Other */ + /* Literal.String.Regex */ + /* Literal.String.Single */ + /* Literal.String.Symbol */ + /* Name.Builtin.Pseudo */ + /* Name.Variable.Class */ + /* Name.Variable.Global */ + /* Name.Variable.Instance */ + /* Literal.Number.Integer.Long */ +} +/* line 200, ../_sass/main.scss */ +.docs-content h3 { + margin-top: 50px; + margin-bottom: 10px; + font-size: 2em; + font-weight: 400; +} +/* line 207, ../_sass/main.scss */ +.docs-content h4 { + font-size: 1.5em; + font-weight: 400; + margin-bottom: 0; +} +/* line 214, ../_sass/main.scss */ +.docs-content p, .docs-content li { + font-family: Helvetica, Arial, sans-serif; + font-size: 0.9em; +} +/* line 220, ../_sass/main.scss */ +.docs-content .highlight { + font-size: 0.85em; + background-color: #ece8e1; + color: #000000; +} +/* line 226, ../_sass/main.scss */ +.docs-content .highlight .hll { + background-color: #ffffcc; +} +/* line 227, ../_sass/main.scss */ +.docs-content .highlight .c { + color: #aaaaaa; + font-style: italic; +} +/* line 228, ../_sass/main.scss */ +.docs-content .highlight .err { + color: #F00000; + background-color: #F0A0A0; +} +/* line 229, ../_sass/main.scss */ +.docs-content .highlight .k { + color: #0000aa; +} +/* line 230, ../_sass/main.scss */ +.docs-content .highlight .cm { + color: #aaaaaa; + font-style: italic; +} +/* line 231, ../_sass/main.scss */ +.docs-content .highlight .cp { + color: #4c8317; +} +/* line 232, ../_sass/main.scss */ +.docs-content .highlight .c1 { + color: #aaaaaa; + font-style: italic; +} +/* line 233, ../_sass/main.scss */ +.docs-content .highlight .cs { + color: #0000aa; + font-style: italic; +} +/* line 234, ../_sass/main.scss */ +.docs-content .highlight .gd { + color: #aa0000; +} +/* line 235, ../_sass/main.scss */ +.docs-content .highlight .ge { + font-style: italic; +} +/* line 236, ../_sass/main.scss */ +.docs-content .highlight .gr { + color: #aa0000; +} +/* line 237, ../_sass/main.scss */ +.docs-content .highlight .gh { + color: #000080; + font-weight: bold; +} +/* line 238, ../_sass/main.scss */ +.docs-content .highlight .gi { + color: #00aa00; +} +/* line 239, ../_sass/main.scss */ +.docs-content .highlight .go { + color: #888888; +} +/* line 240, ../_sass/main.scss */ +.docs-content .highlight .gp { + color: #555555; +} +/* line 241, ../_sass/main.scss */ +.docs-content .highlight .gs { + font-weight: bold; +} +/* line 242, ../_sass/main.scss */ +.docs-content .highlight .gu { + color: #800080; + font-weight: bold; +} +/* line 243, ../_sass/main.scss */ +.docs-content .highlight .gt { + color: #aa0000; +} +/* line 244, ../_sass/main.scss */ +.docs-content .highlight .kc { + color: #0000aa; +} +/* line 245, ../_sass/main.scss */ +.docs-content .highlight .kd { + color: #0000aa; +} +/* line 246, ../_sass/main.scss */ +.docs-content .highlight .kn { + color: #0000aa; +} +/* line 247, ../_sass/main.scss */ +.docs-content .highlight .kp { + color: #0000aa; +} +/* line 248, ../_sass/main.scss */ +.docs-content .highlight .kr { + color: #0000aa; +} +/* line 249, ../_sass/main.scss */ +.docs-content .highlight .kt { + color: #00aaaa; +} +/* line 250, ../_sass/main.scss */ +.docs-content .highlight .m { + color: #009999; +} +/* line 251, ../_sass/main.scss */ +.docs-content .highlight .n { + color: #000000; +} +/* line 252, ../_sass/main.scss */ +.docs-content .highlight .p { + color: #000000; +} +/* line 253, ../_sass/main.scss */ +.docs-content .highlight .s { + color: #aa5500; +} +/* line 254, ../_sass/main.scss */ +.docs-content .highlight .na { + color: #1e90ff; +} +/* line 255, ../_sass/main.scss */ +.docs-content .highlight .nb { + color: #00aaaa; +} +/* line 256, ../_sass/main.scss */ +.docs-content .highlight .nc { + color: #00aa00; + text-decoration: underline; +} +/* line 257, ../_sass/main.scss */ +.docs-content .highlight .no { + color: #aa0000; +} +/* line 258, ../_sass/main.scss */ +.docs-content .highlight .nd { + color: #888888; +} +/* line 259, ../_sass/main.scss */ +.docs-content .highlight .ni { + color: #800000; + font-weight: bold; +} +/* line 260, ../_sass/main.scss */ +.docs-content .highlight .nf { + color: #00aa00; +} +/* line 261, ../_sass/main.scss */ +.docs-content .highlight .nn { + color: #00aaaa; + text-decoration: underline; +} +/* line 262, ../_sass/main.scss */ +.docs-content .highlight .nt { + color: #1e90ff; + font-weight: bold; +} +/* line 263, ../_sass/main.scss */ +.docs-content .highlight .nv { + color: #aa0000; +} +/* line 264, ../_sass/main.scss */ +.docs-content .highlight .ow { + color: #0000aa; +} +/* line 265, ../_sass/main.scss */ +.docs-content .highlight .w { + color: #bbbbbb; +} +/* line 266, ../_sass/main.scss */ +.docs-content .highlight .mf { + color: #009999; +} +/* line 267, ../_sass/main.scss */ +.docs-content .highlight .mh { + color: #009999; +} +/* line 268, ../_sass/main.scss */ +.docs-content .highlight .mi { + color: #009999; +} +/* line 269, ../_sass/main.scss */ +.docs-content .highlight .mo { + color: #009999; +} +/* line 270, ../_sass/main.scss */ +.docs-content .highlight .sb { + color: #aa5500; +} +/* line 271, ../_sass/main.scss */ +.docs-content .highlight .sc { + color: #aa5500; +} +/* line 272, ../_sass/main.scss */ +.docs-content .highlight .sd { + color: #aa5500; +} +/* line 273, ../_sass/main.scss */ +.docs-content .highlight .s2 { + color: #aa5500; +} +/* line 274, ../_sass/main.scss */ +.docs-content .highlight .se { + color: #aa5500; +} +/* line 275, ../_sass/main.scss */ +.docs-content .highlight .sh { + color: #aa5500; +} +/* line 276, ../_sass/main.scss */ +.docs-content .highlight .si { + color: #aa5500; +} +/* line 277, ../_sass/main.scss */ +.docs-content .highlight .sx { + color: #aa5500; +} +/* line 278, ../_sass/main.scss */ +.docs-content .highlight .sr { + color: #009999; +} +/* line 279, ../_sass/main.scss */ +.docs-content .highlight .s1 { + color: #aa5500; +} +/* line 280, ../_sass/main.scss */ +.docs-content .highlight .ss { + color: #0000aa; +} +/* line 281, ../_sass/main.scss */ +.docs-content .highlight .bp { + color: #00aaaa; +} +/* line 282, ../_sass/main.scss */ +.docs-content .highlight .vc { + color: #aa0000; +} +/* line 283, ../_sass/main.scss */ +.docs-content .highlight .vg { + color: #aa0000; +} +/* line 284, ../_sass/main.scss */ +.docs-content .highlight .vi { + color: #aa0000; +} +/* line 285, ../_sass/main.scss */ +.docs-content .highlight .il { + color: #009999; +} From 9eed4a1d14b6eca4aeb6b419f5fca5101e2bbb81 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Sat, 25 Oct 2014 14:37:41 -0400 Subject: [PATCH 0310/3836] Create layout based on documentation page. --- docs/_includes/footer.html | 8 + docs/_includes/google-analytics.html | 16 ++ docs/_includes/head.html | 7 + docs/_includes/toc.html | 97 ++++++++++ docs/_includes/top-menu.html | 9 + docs/_layouts/default.html | 21 +++ docs/documentation.html | 272 +++++++-------------------- docs/index.html | 47 +---- 8 files changed, 228 insertions(+), 249 deletions(-) create mode 100644 docs/_includes/footer.html create mode 100644 docs/_includes/google-analytics.html create mode 100644 docs/_includes/head.html create mode 100644 docs/_includes/toc.html create mode 100644 docs/_includes/top-menu.html create mode 100644 docs/_layouts/default.html diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html new file mode 100644 index 00000000000..7f555209577 --- /dev/null +++ b/docs/_includes/footer.html @@ -0,0 +1,8 @@ +
      + Copyright 2011 Greg Bell and VersaPay +
      +
      +

      +
      +

      diff --git a/docs/_includes/google-analytics.html b/docs/_includes/google-analytics.html new file mode 100644 index 00000000000..7d4aa11830f --- /dev/null +++ b/docs/_includes/google-analytics.html @@ -0,0 +1,16 @@ + diff --git a/docs/_includes/head.html b/docs/_includes/head.html new file mode 100644 index 00000000000..aec28a6da67 --- /dev/null +++ b/docs/_includes/head.html @@ -0,0 +1,7 @@ + + Active Admin | The administration framework for Ruby on Rails + + + + + \ No newline at end of file diff --git a/docs/_includes/toc.html b/docs/_includes/toc.html new file mode 100644 index 00000000000..3664cf36609 --- /dev/null +++ b/docs/_includes/toc.html @@ -0,0 +1,97 @@ +
        +
      1. Gem compatibility
      2. +
          +
        1. Gemfile
        2. +
        3. Initialize Active Admin
        4. +
        5. Register your models with Active + Admin
        6. +
        7. will_paginate compatibility
        8. +
        +
      3. General Configuration
      4. +
          +
        1. Authentication
        2. +
        3. Site Title Options
        4. +
        5. Internationalization (I18n)
        6. +
        7. Namespaces
        8. +
        9. Load paths
        10. +
        11. Comments
        12. +
        13. Utility Navigation
        14. +
        +
      5. Customize The Resource
      6. +
          +
        1. Rename the Resource
        2. +
        3. Customize the Namespace
        4. +
        5. Customize the Menu
        6. +
        7. Scoping the queries
        8. +
        9. Customizing resource + retrieval
        10. +
        11. Belongs To
        12. +
        +
      7. Customizing the Index Page
      8. +
          +
        1. Create an Index
        2. +
        3. Index as a Block
        4. +
        5. Index as Blog
        6. +
        7. Index as a Grid
        8. +
        9. Index as a Table
        10. +
        +
      9. Customizing the CSV format
      10. +
      11. Customizing the Form
      12. +
          +
        1. Nested Resources
        2. +
        3. Displaying Errors
        4. +
        +
      13. Customize the Show Page
      14. +
      15. Sidebar Sections
      16. +
      17. Custom Controller Actions
      18. +
          +
        1. Collection Actions
        2. +
        3. Member Actions
        4. +
        5. Controller Action HTTP Verb
        6. +
        7. Rendering in Custom Actions
        8. +
        9. Modify the Controller
        10. +
        +
      19. Index Batch Actions
      20. +
          +
        1. Provided Batch Action
        2. +
        3. Creating Your Own Batch Actions
        4. +
        +
      21. Custom Pages
      22. +
          +
        1. Available Features
        2. +
        3. Create a new Page
        4. +
        5. Page Title & I18n
        6. +
        7. Customize the Menu
        8. +
        9. Add a Sidebar Section
        10. +
        11. Add an Action Item
        12. +
        13. Add a Page Action
        14. +
        +
      23. Decorators
      24. +
          +
        1. Configuration
        2. +
        3. Example Usage
        4. +
        5. Forms
        6. +
        +
      25. Arbre Components
      26. +
          +
        1. Text Node
        2. +
        3. Panels
        4. +
        5. Columns
        6. +
        7. Table For
        8. +
        9. Status tag
        10. +
        +
      27. Authorization Adapter
      28. +
          +
        1. Setting up your own + AuthorizationAdapter
        2. +
        3. Getting Access to the + Current User
        4. +
        5. Scoping + Collections in Authorization Adapters
        6. +
        7. Managing Access to Pages
        8. +
        9. Action Types
        10. +
        11. Checking + for Authorization in Controllers and Views
        12. +
        13. Using the CanCan Adapter
        14. +
        +
      diff --git a/docs/_includes/top-menu.html b/docs/_includes/top-menu.html new file mode 100644 index 00000000000..0154a5a4dcf --- /dev/null +++ b/docs/_includes/top-menu.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 00000000000..6de317f786a --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,21 @@ + + +{% include head.html %} + +
      + {% include top-menu.html %} +
      +
      + {% include toc.html %} +
      +
      +
      + {{ content }} +
      +
      +
      + {% include footer.html %} +
      + {% include google-analytics.html %} + + \ No newline at end of file diff --git a/docs/documentation.html b/docs/documentation.html index 20afd6d665b..7965198c7a2 100644 --- a/docs/documentation.html +++ b/docs/documentation.html @@ -1,224 +1,80 @@ - - - - - - Active Admin | The administration framework for Ruby on Rails - - - - - - - - - - -
      -
      + + + + +
      +

      The administration framework for business critical Ruby on Rails applications.

      +

      Active Admin is a Ruby on Rails plugin for generating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort.

      +

      A beautiful interface designed for real people.

      +
      +
      +

      Global Navigation

      +

      Customizable global navigation allows you to create usable admin interfaces for your business.

      +

      Scopes

      +

      Use scopes to create sections of mutually exlusive resources for quick navigation and reporting.

      +

      Index Styles

      +

      Index screens are available in many styles. The default, shown here, is a table view, but Active Admin also supports Grids, Blocks and a Blog view.

      +

      API & Downloads

      +

      Each resource that is registered wtih Active Admin becomes available as JSON, XML and CSV download. Customize the output to meet your requirements.

      +
      +
      +

      User Authentication

      +

      Use the bundled Devise configuration or implement your own authorization using the provided hooks.

      +

      Action Items

      +

      Add buttons, links or other content in the “Action Items” section on each screen.

      +

      Filters

      +

      Allow users to filter resources by searching strings, text fields, dates, and numeric values.

      +

      Sidebar Sections

      +

      Customize the sidebar sections with a simple DSL built in to Active Admin.

      +
      +
      +

      Active Admin’s interface was designed from the ground up for non-technical users. It makes it easy for developers to build highly usable interfaces that customers will actually enjoy using.

      +

      An elegant DSL built for developer productivity.

      +

      Get started with one line of code or customize the entire interface with the provided DSL.

      +
      +
      # app/admin/posts.rb
      +ActiveAdmin.register Product do
      +
      +  # Create sections on the index screen
      +  scope :all, :default => true
      +  scope :available
      +  scope :drafts
      +
      +  # Filterable attributes on the index screen
      +  filter :title
      +  filter :author, :as => :select, :collection => lambda{ Product.authors }
      +  filter :price
      +  filter :created_at
      +
      +  # Customize columns displayed on the index screen in the table
      +  index do
      +    column :title
      +    column "Price", :sortable => :price do |product|
      +      number_to_currency product.price
      +    end
      +    default_actions
      +  end
      +
      +end
      +
      +
      +
      +

      3 Ways to Get Started:

      +

      Check Out the Live Demo Read The Documentation Visit the Git Repository

      +
      + +
      + Copyright 2011 Greg Bell and VersaPay +
      +
      +

      +
      +

      + + +
    + diff --git a/docs/index.html b/docs/index.html index 3c2f6744436..e0c91078d4a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,30 +1,15 @@ +--- +--- - - - Active Admin | The administration framework for Ruby on Rails - - - - - - - +{% include head.html %}
    - - + {% include top-menu.html %}

    The administration framework for business critical Ruby on Rails applications.

    @@ -87,33 +72,13 @@

    3 Ways to Get Started:

    Check Out the Live Demo Read The Documentation Visit the Git Repository

    -
    - Copyright 2011 Greg Bell and VersaPay -
    -
    -

    -
    -

    +{% include footer.html %}
    - - - From 609d3ed558b8371ebaecfdedc2276aedd4f87c83 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Mon, 27 Oct 2014 01:26:30 +0100 Subject: [PATCH 0311/3836] pretty format html --- docs/_layouts/default.html | 38 ++++---- docs/documentation.html | 173 +++++++++++++++++++++---------------- docs/index.html | 160 ++++++++++++++++++++++------------ 3 files changed, 219 insertions(+), 152 deletions(-) diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index 6de317f786a..8bc396bf5bf 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -1,21 +1,21 @@ -{% include head.html %} - -
    - {% include top-menu.html %} -
    -
    - {% include toc.html %} -
    -
    -
    - {{ content }} -
    -
    -
    - {% include footer.html %} -
    - {% include google-analytics.html %} - - \ No newline at end of file + {% include head.html %} + +
    + {% include top-menu.html %} +
    +
    + {% include toc.html %} +
    +
    +
    + {{ content }} +
    +
    +
    + {% include footer.html %} +
    + {% include google-analytics.html %} + + diff --git a/docs/documentation.html b/docs/documentation.html index 7965198c7a2..3c150e26f93 100644 --- a/docs/documentation.html +++ b/docs/documentation.html @@ -1,80 +1,101 @@ --- layout: default --- -

    - - Documentation : - - Active Admin Documentation -

    - -
    -

    Active Admin is a framework for creating administration style interfaces. It abstracts common business - application patterns to make it simple for developers to implement beautiful and elegant interfaces with very - little effort.

    - -

    Getting Started

    - -

    Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails 3 application. To - install, simply add the following to your Gemfile:

    - -
     # Gemfile
    -        gem 'activeadmin'
    -    
    + + + + + + +

    + Documentation : Active Admin Documentation +

    +
    +

    + Active Admin is a framework for creating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort. +

    +

    + Getting Started +

    +

    + Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails 3 application. To install, simply add the following to your Gemfile: +

    +
    +
    +  # Gemfile
    +  gem 'activeadmin'
    +
    +

    + If you are using Rails >= 3.1, you must also include a beta version of MetaSearch and sass-rails: +

    +
    +
    +  # Gemfile in Rails >= 3.1
    +  gem 'activeadmin'
    +  gem 'sass-rails'
    +  gem "meta_search", '>= 1.1.0.pre'
    +
    +

    + After updating your bundle, run the installer +

    +
    +
     $> rails generate active_admin:install 
    +
    +

    + The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at app/admin to put all your admin configurations. +

    +

    + Migrate your db and start the server: +

    +
    +
    +  $> rake db:migrate
    +  $> rails server
    +
    +

    + Visit http://localhost:3000/admin and log in using: +

    +
      +
    • + User: admin@example.com +
    • +
    • + Password: password +
    • +
    +

    + Voila! You're on your brand new Active Admin dashboard. +

    +

    + To register your first model, run: +

    +
    +
    + $> rails generate active_admin:resource [MyModelName]
    +
    +

    + This creates a file at app/admin/my_model_names.rb for configuring the resource. Refresh your web browser to see the interface. +

    +

    + Next Steps +

    +

    + Now that you have a working Active Admin installation, learn how to customize it: +

    +
    -

    If you are using Rails >= 3.1, you must also include a beta version of MetaSearch and sass-rails:

    - -
     # Gemfile in Rails >= 3.1
    -        gem 'activeadmin'
    -        gem 'sass-rails'
    -        gem "meta_search", '>= 1.1.0.pre'
    -    
    -
    -

    After updating your bundle, run the installer

    - -
     $> rails generate active_admin:install
    -    
    -
    -

    The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder - at app/admin to put all your admin configurations.

    - -

    Migrate your db and start the server:

    - -
     $> rake db:migrate
    -        $> rails server
    -    
    -
    -

    Visit http://localhost:3000/admin and log in using:

    - -
      -
    • User: admin@example.com
    • - -
    • Password: password
    • -
    - -

    Voila! You’re on your brand new Active Admin dashboard.

    - -

    To register your first model, run:

    - -
     $> rails generate active_admin:resource
    -        [MyModelName]
    -    
    -
    -

    This creates a file at app/admin/my_model_names.rb for configuring the resource. Refresh your web - browser to see the interface.

    - -

    Next Steps

    - -

    Now that you have a working Active Admin installation, learn how to customize it:

    - - -
    + + diff --git a/docs/index.html b/docs/index.html index e0c91078d4a..8e2f281fa97 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,47 +1,93 @@ --- --- - + - -{% include head.html %} - - - -
    - - {% include top-menu.html %} - -
    -

    The administration framework for business critical Ruby on Rails applications.

    -

    Active Admin is a Ruby on Rails plugin for generating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort.

    -

    A beautiful interface designed for real people.

    -
    -
    -

    Global Navigation

    -

    Customizable global navigation allows you to create usable admin interfaces for your business.

    -

    Scopes

    -

    Use scopes to create sections of mutually exlusive resources for quick navigation and reporting.

    -

    Index Styles

    -

    Index screens are available in many styles. The default, shown here, is a table view, but Active Admin also supports Grids, Blocks and a Blog view.

    -

    API & Downloads

    -

    Each resource that is registered wtih Active Admin becomes available as JSON, XML and CSV download. Customize the output to meet your requirements.

    -
    -
    -

    User Authentication

    -

    Use the bundled Devise configuration or implement your own authorization using the provided hooks.

    -

    Action Items

    -

    Add buttons, links or other content in the “Action Items” section on each screen.

    -

    Filters

    -

    Allow users to filter resources by searching strings, text fields, dates, and numeric values.

    -

    Sidebar Sections

    -

    Customize the sidebar sections with a simple DSL built in to Active Admin.

    -
    -
    -

    Active Admin’s interface was designed from the ground up for non-technical users. It makes it easy for developers to build highly usable interfaces that customers will actually enjoy using.

    -

    An elegant DSL built for developer productivity.

    -

    Get started with one line of code or customize the entire interface with the provided DSL.

    -
    -
    # app/admin/posts.rb
    +  
    +    
    +  
    +  
    +    

    + {% include head.html %} +

    +
    + {% include top-menu.html %} +
    +

    + The administration framework for business critical Ruby on Rails applications. +

    +

    + Active Admin is a Ruby on Rails plugin for generating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort. +

    +

    + A beautiful interface designed for real people. +

    +
    +
    +

    + Global Navigation +

    +

    + Customizable global navigation allows you to create usable admin interfaces for your business. +

    +

    + Scopes +

    +

    + Use scopes to create sections of mutually exlusive resources for quick navigation and reporting. +

    +

    + Index Styles +

    +

    + Index screens are available in many styles. The default, shown here, is a table view, but Active Admin also supports Grids, Blocks and a Blog view. +

    +

    + API & Downloads +

    +

    + Each resource that is registered wtih Active Admin becomes available as JSON, XML and CSV download. Customize the output to meet your requirements. +

    +
    +
    +

    + User Authentication +

    +

    + Use the bundled Devise configuration or implement your own authorization using the provided hooks. +

    +

    + Action Items +

    +

    + Add buttons, links or other content in the “Action Items” section on each screen. +

    +

    + Filters +

    +

    + Allow users to filter resources by searching strings, text fields, dates, and numeric values. +

    +

    + Sidebar Sections +

    +

    + Customize the sidebar sections with a simple DSL built in to Active Admin. +

    +
    +
    +

    + Active Admin’s interface was designed from the ground up for non-technical users. It makes it easy for developers to build highly usable interfaces that customers will actually enjoy using. +

    +

    + An elegant DSL built for developer productivity. +

    +

    + Get started with one line of code or customize the entire interface with the provided DSL. +

    +
    +
    +
    +# app/admin/posts.rb
     ActiveAdmin.register Product do
     
       # Create sections on the index screen
    @@ -58,27 +104,27 @@ 

    An elegant DSL built for developer productivity.# Customize columns displayed on the index screen in the table index do column :title - column "Price", :sortable => :price do |product| + column "Price", :sortable => :price do |product| number_to_currency product.price end default_actions end end -

    -
    -
    -

    3 Ways to Get Started:

    -

    Check Out the Live Demo Read The Documentation Visit the Git Repository

    +
    +
    +
    +
    +

    + 3 Ways to Get Started: +

    +

    + Check Out the Live Demo Read The Documentation Visit the Git Repository +

    +
    {% include footer.html %}
    - -{% include footer.html %} - - -
    - -{% include google-analytics.html %} - - - +

    + {% include google-analytics.html %} +

    + From dd2715ec52957464b1e4c1712814d0206138d027 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Mon, 27 Oct 2014 01:29:49 +0100 Subject: [PATCH 0312/3836] Fix TOC links, top menu link and repo url. --- docs/_includes/toc.html | 134 +++++++++++++++++------------------ docs/_includes/top-menu.html | 4 +- docs/index.html | 2 +- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/docs/_includes/toc.html b/docs/_includes/toc.html index 3664cf36609..347e1da9b5a 100644 --- a/docs/_includes/toc.html +++ b/docs/_includes/toc.html @@ -1,97 +1,97 @@
      -
    1. Gem compatibility
    2. +
    3. Gem compatibility
      1. -
      2. Gemfile
      3. -
      4. Initialize Active Admin
      5. -
      6. Register your models with Active +
      7. Gemfile
      8. +
      9. Initialize Active Admin
      10. +
      11. Register your models with Active Admin
      12. -
      13. will_paginate compatibility
      14. +
      15. will_paginate compatibility
      -
    4. General Configuration
    5. +
    6. General Configuration
      1. -
      2. Authentication
      3. -
      4. Site Title Options
      5. -
      6. Internationalization (I18n)
      7. -
      8. Namespaces
      9. -
      10. Load paths
      11. -
      12. Comments
      13. -
      14. Utility Navigation
      15. +
      16. Authentication
      17. +
      18. Site Title Options
      19. +
      20. Internationalization (I18n)
      21. +
      22. Namespaces
      23. +
      24. Load paths
      25. +
      26. Comments
      27. +
      28. Utility Navigation
      -
    7. Customize The Resource
    8. +
    9. Customize The Resource
      1. -
      2. Rename the Resource
      3. -
      4. Customize the Namespace
      5. -
      6. Customize the Menu
      7. -
      8. Scoping the queries
      9. -
      10. Customizing resource +
      11. Rename the Resource
      12. +
      13. Customize the Namespace
      14. +
      15. Customize the Menu
      16. +
      17. Scoping the queries
      18. +
      19. Customizing resource retrieval
      20. -
      21. Belongs To
      22. +
      23. Belongs To
      -
    10. Customizing the Index Page
    11. +
    12. Customizing the Index Page
      1. -
      2. Create an Index
      3. -
      4. Index as a Block
      5. -
      6. Index as Blog
      7. -
      8. Index as a Grid
      9. -
      10. Index as a Table
      11. +
      12. Create an Index
      13. +
      14. Index as a Block
      15. +
      16. Index as Blog
      17. +
      18. Index as a Grid
      19. +
      20. Index as a Table
      -
    13. Customizing the CSV format
    14. -
    15. Customizing the Form
    16. +
    17. Customizing the CSV format
    18. +
    19. Customizing the Form
      1. -
      2. Nested Resources
      3. -
      4. Displaying Errors
      5. +
      6. Nested Resources
      7. +
      8. Displaying Errors
      -
    20. Customize the Show Page
    21. -
    22. Sidebar Sections
    23. -
    24. Custom Controller Actions
    25. +
    26. Customize the Show Page
    27. +
    28. Sidebar Sections
    29. +
    30. Custom Controller Actions
      1. -
      2. Collection Actions
      3. -
      4. Member Actions
      5. -
      6. Controller Action HTTP Verb
      7. -
      8. Rendering in Custom Actions
      9. -
      10. Modify the Controller
      11. +
      12. Collection Actions
      13. +
      14. Member Actions
      15. +
      16. Controller Action HTTP Verb
      17. +
      18. Rendering in Custom Actions
      19. +
      20. Modify the Controller
      -
    31. Index Batch Actions
    32. +
    33. Index Batch Actions
      1. -
      2. Provided Batch Action
      3. -
      4. Creating Your Own Batch Actions
      5. +
      6. Provided Batch Action
      7. +
      8. Creating Your Own Batch Actions
      -
    34. Custom Pages
    35. +
    36. Custom Pages
      1. -
      2. Available Features
      3. -
      4. Create a new Page
      5. -
      6. Page Title & I18n
      7. -
      8. Customize the Menu
      9. -
      10. Add a Sidebar Section
      11. -
      12. Add an Action Item
      13. -
      14. Add a Page Action
      15. +
      16. Available Features
      17. +
      18. Create a new Page
      19. +
      20. Page Title & I18n
      21. +
      22. Customize the Menu
      23. +
      24. Add a Sidebar Section
      25. +
      26. Add an Action Item
      27. +
      28. Add a Page Action
      -
    37. Decorators
    38. +
    39. Decorators
      1. -
      2. Configuration
      3. -
      4. Example Usage
      5. -
      6. Forms
      7. +
      8. Configuration
      9. +
      10. Example Usage
      11. +
      12. Forms
      -
    40. Arbre Components
    41. +
    42. Arbre Components
      1. -
      2. Text Node
      3. -
      4. Panels
      5. -
      6. Columns
      7. -
      8. Table For
      9. -
      10. Status tag
      11. +
      12. Text Node
      13. +
      14. Panels
      15. +
      16. Columns
      17. +
      18. Table For
      19. +
      20. Status tag
      -
    43. Authorization Adapter
    44. +
    45. Authorization Adapter
      1. -
      2. Setting up your own +
      3. Setting up your own AuthorizationAdapter
      4. -
      5. Getting Access to the +
      6. Getting Access to the Current User
      7. -
      8. Scoping +
      9. Scoping Collections in Authorization Adapters
      10. -
      11. Managing Access to Pages
      12. -
      13. Action Types
      14. -
      15. Checking +
      16. Managing Access to Pages
      17. +
      18. Action Types
      19. +
      20. Checking for Authorization in Controllers and Views
      21. -
      22. Using the CanCan Adapter
      23. +
      24. Using the CanCan Adapter
    diff --git a/docs/_includes/top-menu.html b/docs/_includes/top-menu.html index 0154a5a4dcf..517e2914875 100644 --- a/docs/_includes/top-menu.html +++ b/docs/_includes/top-menu.html @@ -2,8 +2,8 @@

    Active Admin

    \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 8e2f281fa97..55683249a0d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -119,7 +119,7 @@

    3 Ways to Get Started:

    - Check Out the Live Demo Read The Documentation Visit the Git Repository + Check Out the Live Demo Read The Documentation Visit the Git Repository

    {% include footer.html %} From 11459c34863bb1fdb875554ae287c8bdc8370747 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Sat, 1 Nov 2014 11:30:50 -0400 Subject: [PATCH 0313/3836] Rename documentation.html to documentation.md --- docs/{documentation.html => documentation.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{documentation.html => documentation.md} (100%) diff --git a/docs/documentation.html b/docs/documentation.md similarity index 100% rename from docs/documentation.html rename to docs/documentation.md From c0b90d33e48ac533479ff550c382f6ba049fd990 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Sat, 1 Nov 2014 17:18:42 -0400 Subject: [PATCH 0314/3836] Convert documentation front page back into markdown, remove reference to MetaSearch and reference Rails 4 supported by master. --- docs/documentation.md | 157 ++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 98 deletions(-) diff --git a/docs/documentation.md b/docs/documentation.md index 3c150e26f93..c4135ed19fd 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -1,101 +1,62 @@ --- layout: default --- - - - - - - -

    - Documentation : Active Admin Documentation -

    -
    -

    - Active Admin is a framework for creating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort. -

    -

    - Getting Started -

    -

    - Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails 3 application. To install, simply add the following to your Gemfile: -

    -
    -
    -  # Gemfile
    -  gem 'activeadmin'
    -
    -

    - If you are using Rails >= 3.1, you must also include a beta version of MetaSearch and sass-rails: -

    -
    -
    -  # Gemfile in Rails >= 3.1
    -  gem 'activeadmin'
    -  gem 'sass-rails'
    -  gem "meta_search", '>= 1.1.0.pre'
    -
    -

    - After updating your bundle, run the installer -

    -
    -
     $> rails generate active_admin:install 
    -
    -

    - The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at app/admin to put all your admin configurations. -

    -

    - Migrate your db and start the server: -

    -
    -
    -  $> rake db:migrate
    -  $> rails server
    -
    -

    - Visit http://localhost:3000/admin and log in using: -

    -
      -
    • - User: admin@example.com -
    • -
    • - Password: password -
    • -
    -

    - Voila! You're on your brand new Active Admin dashboard. -

    -

    - To register your first model, run: -

    -
    -
    - $> rails generate active_admin:resource [MyModelName]
    -
    -

    - This creates a file at app/admin/my_model_names.rb for configuring the resource. Refresh your web browser to see the interface. -

    -

    - Next Steps -

    -

    - Now that you have a working Active Admin installation, learn how to customize it: -

    - -
    - - +

    + + Documentation : + + Active Admin Documentation +

    + +Active Admin is a framework for creating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very +little effort. + +### Getting Started + +Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails 4 application. To + install, simply add the following to your Gemfile:

    + +```ruby +# Gemfile +gem 'activeadmin', github: 'activeadmin' +``` + +After updating your bundle, run the installer + +```bash +rails generate active_admin:install +``` + +The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at app/admin to put all your admin configurations. + +Migrate your db and start the server: + +```bash +$> rake db:migrate +$> rails server +``` + +Visit http://localhost:3000/admin and log in using: + +* User: admin@example.com +* Password: password + +Voila! You’re on your brand new Active Admin dashboard. + +To register your first model, run: + +```bash +$> rails generate active_admin:resource + [MyModelName] +``` + +This creates a file at app/admin/my_model_names.rb for configuring the resource. Refresh your web browser to see the interface.

    + +### Next Steps + +Now that you have a working Active Admin installation, learn how to customize it: + +* Customize the Index Page +* Customize the New and Edit Form +* Customize the Show Page +* Customize the Resource in General From 85a36eeeded20b1c33eb15c070ee83e4805dc793 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Sun, 26 Oct 2014 10:49:41 -0400 Subject: [PATCH 0315/3836] Publish as www.activeadmin.info --- docs/CNAME | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/CNAME diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 00000000000..df3be36a340 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +www.activeadmin.info \ No newline at end of file From 9f157bb178ec76dd55dca630664f8bf44d8e6abc Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sun, 19 Feb 2017 17:29:28 +0200 Subject: [PATCH 0316/3836] added features to test actions support with multiple HTTP methods --- features/registering_pages.feature | 30 +++++++++++++++++++++++++++++ features/specifying_actions.feature | 25 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/features/registering_pages.feature b/features/registering_pages.feature index 0756efc6993..ac531b05986 100644 --- a/features/registering_pages.feature +++ b/features/registering_pages.feature @@ -106,6 +106,36 @@ Feature: Registering Pages And I follow "Status" Then I should see an action item link to "Visit" + Scenario: Adding a page action to a page with multiple http methods + Given a configuration of: + """ + ActiveAdmin.register_page "Status" do + page_action :check, method: [:get, :post] do + redirect_to admin_status_path, notice: "Checked via #{request.method}" + end + + action_item :post_check do + link_to "Post Check", admin_status_check_path, method: :post + end + + action_item :get_check do + link_to "Get Check", admin_status_check_path + end + + content do + "I love chocolate." + end + end + """ + When I go to the dashboard + And I follow "Status" + And I follow "Post Check" + Then I should see "Checked via POST" + And I should see the Active Admin layout + When I follow "Get Check" + Then I should see "Checked via GET" + And I should see the Active Admin layout + Scenario: Adding a page action to a page Given a configuration of: """ diff --git a/features/specifying_actions.feature b/features/specifying_actions.feature index 39c93b47a3e..926938ba4c6 100644 --- a/features/specifying_actions.feature +++ b/features/specifying_actions.feature @@ -91,3 +91,28 @@ Feature: Specifying Actions And I should see the page title "Review" And I should see the Active Admin layout + Scenario: Specify a custom member action with multiple http methods + Given a configuration of: + """ + ActiveAdmin.register Post do + action_item(:get_check, only: :show) do + link_to('Get Check', check_admin_post_path) + end + + action_item(:post_check, only: :show) do + link_to('Post Check', check_admin_post_path, method: :post) + end + + member_action :check, method: [:get, :post] do + redirect_to admin_post_path(resource), notice: "Checked via #{request.method}" + end + end + """ + And I am logged in + And a post with the title "Hello World" exists + When I am on the index page for posts + And I follow "View" + And I follow "Get Check" + Then I should see "Checked via GET" + When I follow "Post Check" + Then I should see "Checked via POST" \ No newline at end of file From 6119604e17beed3753484d8dd90d5fbe6e6a71a0 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sun, 19 Feb 2017 17:58:29 +0200 Subject: [PATCH 0317/3836] multiple http method support added to page actions fixes #4795 --- docs/10-custom-pages.md | 9 +++++++++ lib/active_admin/router.rb | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/10-custom-pages.md b/docs/10-custom-pages.md index 2d288b1d6d9..108c59758b3 100644 --- a/docs/10-custom-pages.md +++ b/docs/10-custom-pages.md @@ -117,3 +117,12 @@ end This defines the route `/admin/calendar/add_event` which can handle HTTP POST requests. Clicking on the action item will reload page and display the message "Your event was added" + +Page actions can handle multiple HTTP verbs. + +```ruby +page_action :add_event, method: [:get, :post] do + # ... +end +``` +See also the [Custom Actions](8-custom-actions.md#http-verbs) example. \ No newline at end of file diff --git a/lib/active_admin/router.rb b/lib/active_admin/router.rb index 7ec2eddf667..f850db5042b 100644 --- a/lib/active_admin/router.rb +++ b/lib/active_admin/router.rb @@ -97,7 +97,9 @@ def resource_routes(config) page = config.underscored_resource_name get "/#{page}" => "#{page}#index" config.page_actions.each do |action| - build_route.call action.http_verb, "/#{page}/#{action.name}" => "#{page}##{action.name}" + Array.wrap(action.http_verb).each do |verb| + build_route.call verb, "/#{page}/#{action.name}" => "#{page}##{action.name}" + end end else raise "Unsupported config class: #{config.class}" From 5fe190c941f026ed49d9ec6004d995bbf8bde422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 18 Feb 2017 17:03:56 -0200 Subject: [PATCH 0318/3836] Gitignore new generated folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5db25880808..fee48a2715d 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ public .rails-version .rbenv-version .localeapp/* +lib/bug_report_templates/tmp From 97b0a5fe0fb3169766d044c43d7152451e76b8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 19:29:43 -0300 Subject: [PATCH 0319/3836] Cleanup output in bug_report_template test Right now it's too verbose. Just print a dot like the other tests do. --- spec/bug_report_templates_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/bug_report_templates_spec.rb b/spec/bug_report_templates_spec.rb index 316831f2999..c1517dde13c 100644 --- a/spec/bug_report_templates_spec.rb +++ b/spec/bug_report_templates_spec.rb @@ -4,7 +4,10 @@ subject do Bundler.with_clean_env do Dir.chdir(chdir_path) do - system({'ACTIVE_ADMIN_PATH' => active_admin_root}, Gem.ruby, template_path) + system({'ACTIVE_ADMIN_PATH' => active_admin_root}, + Gem.ruby, + template_path, + out: File::NULL) end end end From 13ab1d63605570356a15aaeec74dadb0a0eb4a46 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Mon, 20 Feb 2017 16:04:50 +0100 Subject: [PATCH 0320/3836] fix CNAME --- docs/CNAME | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CNAME b/docs/CNAME index df3be36a340..8413804eb41 100644 --- a/docs/CNAME +++ b/docs/CNAME @@ -1 +1 @@ -www.activeadmin.info \ No newline at end of file +activeadmin.info From 1aa39d501a5624c21540c6fd88fa52e75307a724 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Fri, 28 Nov 2014 00:09:00 +0100 Subject: [PATCH 0321/3836] change hash style to 1.9 syntax --- docs/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/index.html b/docs/index.html index 55683249a0d..6610c14180c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -91,20 +91,20 @@

    ActiveAdmin.register Product do # Create sections on the index screen - scope :all, :default => true + scope :all, default: true scope :available scope :drafts # Filterable attributes on the index screen filter :title - filter :author, :as => :select, :collection => lambda{ Product.authors } + filter :author, as: :select, collection: ->{ Product.authors } filter :price filter :created_at # Customize columns displayed on the index screen in the table index do column :title - column "Price", :sortable => :price do |product| + column "Price", sortable: :price do |product| number_to_currency product.price end default_actions From 6a884ff8d0f7736bf7eea7520b8c72d17b045f31 Mon Sep 17 00:00:00 2001 From: Larry Kim Date: Thu, 12 Mar 2015 16:56:07 +0900 Subject: [PATCH 0322/3836] Fix typo in docs/documentation.html Changed 6-show-screen.html to 6-show-pages.html --- docs/documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/documentation.md b/docs/documentation.md index c4135ed19fd..01eb0ae76e8 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -58,5 +58,5 @@ Now that you have a working Active Admin installation, learn how to customize it * Customize the Index Page * Customize the New and Edit Form -* Customize the Show Page +* Customize the Show Page * Customize the Resource in General From 36ea3dbb604bda2cf188019db8ebf1a76f1ae09d Mon Sep 17 00:00:00 2001 From: Robin Daugherty Date: Wed, 7 Sep 2016 15:49:47 -0500 Subject: [PATCH 0323/3836] Fix double-brace causing Jekyll to hide content --- docs/9-batch-actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/9-batch-actions.md b/docs/9-batch-actions.md index 1b5f52e99ed..f6491b3c9b8 100644 --- a/docs/9-batch-actions.md +++ b/docs/9-batch-actions.md @@ -145,7 +145,7 @@ When you have dynamic form inputs you can pass a proc instead: ```ruby # NOTE: multi-pluck is new to Rails 4 -batch_action :doit, form: ->{{user: User.pluck(:name, :id)}} do |ids, inputs| +batch_action :doit, form: -> { {user: User.pluck(:name, :id)} } do |ids, inputs| User.find(inputs[:user]) # ... end From a13f6abb4eab84c0a764201827b4c0d7f45f04f3 Mon Sep 17 00:00:00 2001 From: Scott Robertson Date: Wed, 22 Apr 2015 20:54:38 +0100 Subject: [PATCH 0324/3836] Change posts to products --- docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 6610c14180c..c44e3b8e575 100644 --- a/docs/index.html +++ b/docs/index.html @@ -87,7 +87,7 @@

    -# app/admin/posts.rb
    +# app/admin/products.rb
     ActiveAdmin.register Product do
     
       # Create sections on the index screen
    
    From 66b4cde074fb931a1417f62fd9a0a9252ae9aa7a Mon Sep 17 00:00:00 2001
    From: Jonathan Chen 
    Date: Sat, 12 Nov 2016 09:01:11 -0500
    Subject: [PATCH 0325/3836] Fix spelling
    
    ---
     docs/index.html | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/docs/index.html b/docs/index.html
    index c44e3b8e575..0c7c28fdf42 100644
    --- a/docs/index.html
    +++ b/docs/index.html
    @@ -33,7 +33,7 @@ 

    Scopes

    - Use scopes to create sections of mutually exlusive resources for quick navigation and reporting. + Use scopes to create sections of mutually exclusive resources for quick navigation and reporting.

    Index Styles From b9a4046b3856c27228253780dbe2e323ca1e0a77 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Mon, 20 Feb 2017 16:13:34 -0500 Subject: [PATCH 0326/3836] TOC fixes from zorab47 --- docs/_includes/toc.html | 92 ++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/docs/_includes/toc.html b/docs/_includes/toc.html index 347e1da9b5a..6a1539ee7a6 100644 --- a/docs/_includes/toc.html +++ b/docs/_includes/toc.html @@ -1,35 +1,33 @@
      -
    1. Gem compatibility
    2. +
    3. Installation
      1. -
      2. Gemfile
      3. -
      4. Initialize Active Admin
      5. -
      6. Register your models with Active - Admin
      7. -
      8. will_paginate compatibility
      9. +
      10. Setting up Active Admin
      11. +
      12. Upgrading
      13. +
      14. Gem Compatibility
    4. General Configuration
      1. Authentication
      2. -
      3. Site Title Options
      4. -
      5. Internationalization (I18n)
      6. +
      7. Site Title Options
      8. +
      9. Internationalization (I18n)
      10. Namespaces
      11. -
      12. Load paths
      13. +
      14. Load paths
      15. Comments
      16. -
      17. Utility Navigation
      18. +
      19. Utility Navigation
      -
    5. Customize The Resource
    6. +
    7. Working with Resources
      1. -
      2. Rename the Resource
      3. -
      4. Customize the Namespace
      5. -
      6. Customize the Menu
      7. -
      8. Scoping the queries
      9. -
      10. Customizing resource +
      11. Rename the Resource
      12. +
      13. Customize the Namespace
      14. +
      15. Customize the Menu
      16. +
      17. Scoping the queries
      18. +
      19. Customizing resource retrieval
      20. -
      21. Belongs To
      22. +
      23. Belongs To
    8. Customizing the Index Page
      1. -
      2. Create an Index
      3. +
      4. Create an Index
      5. Index as a Block
      6. Index as Blog
      7. Index as a Grid
      8. @@ -38,60 +36,62 @@
      9. Customizing the CSV format
      10. Customizing the Form
        1. -
        2. Nested Resources
        3. -
        4. Displaying Errors
        5. +
        6. Default
        7. +
        8. Partials
        9. +
        10. Nested Resources
        11. +
        12. Datepicker
        13. +
        14. Displaying Errors
      11. Customize the Show Page
      12. Sidebar Sections
      13. Custom Controller Actions
        1. -
        2. Collection Actions
        3. -
        4. Member Actions
        5. -
        6. Controller Action HTTP Verb
        7. -
        8. Rendering in Custom Actions
        9. -
        10. Modify the Controller
        11. +
        12. Collection Actions
        13. +
        14. Member Actions
        15. +
        16. HTTP Verbs
        17. +
        18. Rendering
        19. +
        20. Action Items
        21. +
        22. Modifying the Controller
      14. Index Batch Actions
        1. -
        2. Provided Batch Action
        3. -
        4. Creating Your Own Batch Actions
        5. +
        6. Provided Batch Action
        7. +
        8. Creating Your Own
      15. Custom Pages
        1. -
        2. Available Features
        3. -
        4. Create a new Page
        5. -
        6. Page Title & I18n
        7. -
        8. Customize the Menu
        9. -
        10. Add a Sidebar Section
        11. -
        12. Add an Action Item
        13. -
        14. Add a Page Action
        15. +
        16. Create a new Page
        17. +
        18. Customize the Menu
        19. +
        20. Add a Sidebar
        21. +
        22. Add an Action Item
        23. +
        24. Add a Page Action
      16. Decorators
        1. -
        2. Configuration
        3. -
        4. Example Usage
        5. +
        6. Example Usage
        7. Forms
      17. Arbre Components
        1. -
        2. Text Node
        3. +
        4. Text Node
        5. Panels
        6. Columns
        7. -
        8. Table For
        9. -
        10. Status tag
        11. +
        12. Table For
        13. +
        14. Status tag
      18. Authorization Adapter
        1. -
        2. Setting up your own +
        3. Setting up your own AuthorizationAdapter
        4. -
        5. Getting Access to the +
        6. Getting Access to the Current User
        7. -
        8. Scoping +
        9. Scoping Collections in Authorization Adapters
        10. -
        11. Managing Access to Pages
        12. -
        13. Action Types
        14. -
        15. Checking +
        16. Managing Access to Pages
        17. +
        18. Action Types
        19. +
        20. Checking for Authorization in Controllers and Views
        21. -
        22. Using the CanCan Adapter
        23. +
        24. Using the CanCan Adapter
        25. +
        26. Using the Pundit Adapter
      From 7d88eb45a95048c66417f0f0a99b07a447fa1b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 12 Feb 2017 14:40:54 -0200 Subject: [PATCH 0327/3836] Make resource_localizer_spec directly runnable --- spec/unit/localizers/resource_localizer_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/localizers/resource_localizer_spec.rb b/spec/unit/localizers/resource_localizer_spec.rb index 3ebf6185395..2531afa92d5 100644 --- a/spec/unit/localizers/resource_localizer_spec.rb +++ b/spec/unit/localizers/resource_localizer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require File.expand_path('../config_shared_examples', File.dirname(__FILE__)) RSpec.describe ActiveAdmin::Localizers::ResourceLocalizer do From ced8a16a2f4bda2271a007c1ff4f4ae2e151c167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 12 Feb 2017 14:52:59 -0200 Subject: [PATCH 0328/3836] Move shared examples to the only file using them --- spec/unit/config_shared_examples.rb | 13 ------------- spec/unit/localizers/resource_localizer_spec.rb | 14 +++++++++++++- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/spec/unit/config_shared_examples.rb b/spec/unit/config_shared_examples.rb index 696eac52b6e..bd5f90f8c11 100644 --- a/spec/unit/config_shared_examples.rb +++ b/spec/unit/config_shared_examples.rb @@ -57,16 +57,3 @@ end end - -RSpec.shared_examples_for "ActiveAdmin::Localizers::ResourceLocalizer" do - it "should use proper translation" do - string = ActiveAdmin::Localizers::ResourceLocalizer.t(action, model: model, model_name: model_name) - expect(string).to eq translation - end - - it "should accessible via ActiveAdmin::Localizers" do - resource = double(resource_label: model, resource_name: double(i18n_key: model_name)) - localizer = ActiveAdmin::Localizers.resource(resource) - expect(localizer.t(action)).to eq translation - end -end diff --git a/spec/unit/localizers/resource_localizer_spec.rb b/spec/unit/localizers/resource_localizer_spec.rb index 2531afa92d5..976ec437962 100644 --- a/spec/unit/localizers/resource_localizer_spec.rb +++ b/spec/unit/localizers/resource_localizer_spec.rb @@ -1,5 +1,17 @@ require 'rails_helper' -require File.expand_path('../config_shared_examples', File.dirname(__FILE__)) + +RSpec.shared_examples_for "ActiveAdmin::Localizers::ResourceLocalizer" do + it "should use proper translation" do + string = ActiveAdmin::Localizers::ResourceLocalizer.t(action, model: model, model_name: model_name) + expect(string).to eq translation + end + + it "should accessible via ActiveAdmin::Localizers" do + resource = double(resource_label: model, resource_name: double(i18n_key: model_name)) + localizer = ActiveAdmin::Localizers.resource(resource) + expect(localizer.t(action)).to eq translation + end +end RSpec.describe ActiveAdmin::Localizers::ResourceLocalizer do let(:action) { 'new_model' } From b548fc0c8f8e94ac09a6dedb27705d483c6b5f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 13 Feb 2017 09:05:22 -0200 Subject: [PATCH 0329/3836] Fix state leak in `pretty_format_spec` Reproducible with ``` rspec \ ./spec/unit/pretty_format_spec.rb[1:7:2:2:1] \ ./spec/unit/view_helpers/display_helper_spec.rb[1:2:10] \ --seed 1234 ``` --- spec/unit/pretty_format_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/unit/pretty_format_spec.rb b/spec/unit/pretty_format_spec.rb index 0b06ee80dba..de263ac2bde 100644 --- a/spec/unit/pretty_format_spec.rb +++ b/spec/unit/pretty_format_spec.rb @@ -30,11 +30,11 @@ def method_missing(*args, &block) end context "apply custom localize format" do - before do + around do |example| + previous_localize_format = ActiveAdmin.application.localize_format ActiveAdmin.application.localize_format = :short - end - after do - ActiveAdmin.application = nil + example.call + ActiveAdmin.application.localize_format = previous_localize_format end it "should actually do the formatting" do t = Time.utc(1985, "feb", 28, 20, 15, 1) From 5103e66f5aa98b08b7a612115de6f58f77cf8bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 13 Feb 2017 11:38:33 -0200 Subject: [PATCH 0330/3836] Memoize --- spec/unit/resource_registration_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/unit/resource_registration_spec.rb b/spec/unit/resource_registration_spec.rb index 7d5facc4d66..0e1b3fb9664 100644 --- a/spec/unit/resource_registration_spec.rb +++ b/spec/unit/resource_registration_spec.rb @@ -1,10 +1,11 @@ require 'rails_helper' RSpec.describe "Registering an object to administer" do - application = ActiveAdmin::Application.new + let(:application) { ActiveAdmin::Application.new } context "with no configuration" do - namespace = ActiveAdmin::Namespace.new(application, :admin) + let(:namespace) { ActiveAdmin::Namespace.new(application, :admin) } + it "should call register on the namespace" do application.namespaces[namespace.name] = namespace expect(namespace).to receive(:register) From 9639cfe766b8e836ce944894eb40b87d333fc1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 13 Feb 2017 11:39:28 -0200 Subject: [PATCH 0331/3836] Make sure all tests have the necessary setup Fixes ``` rspec ./spec/unit/resource_registration_spec.rb[1:1:2] ``` --- spec/unit/resource_registration_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/unit/resource_registration_spec.rb b/spec/unit/resource_registration_spec.rb index 0e1b3fb9664..ecb7065d9ce 100644 --- a/spec/unit/resource_registration_spec.rb +++ b/spec/unit/resource_registration_spec.rb @@ -6,8 +6,11 @@ context "with no configuration" do let(:namespace) { ActiveAdmin::Namespace.new(application, :admin) } - it "should call register on the namespace" do + before do application.namespaces[namespace.name] = namespace + end + + it "should call register on the namespace" do expect(namespace).to receive(:register) application.register Category @@ -15,6 +18,7 @@ it "should dispatch a Resource::RegisterEvent" do expect(ActiveSupport::Notifications).to receive(:publish).with(ActiveAdmin::Resource::RegisterEvent, an_instance_of(ActiveAdmin::Resource)) + application.register Category end end From b3a8f60d8b32b29ccce9c72b9162f11fdbf2fc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 16 Feb 2017 18:55:23 -0200 Subject: [PATCH 0332/3836] Typo --- spec/rails_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6ece4608d34..7ae1d3557c9 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -27,7 +27,7 @@ def reload_routes! # # Eg: # load_resources do - # ActiveAdmin.regiser(Post) + # ActiveAdmin.register(Post) # end # def load_resources From 7914f346a2d218592f464ad24c0e5d8c712bdbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 16 Feb 2017 20:50:11 -0200 Subject: [PATCH 0333/3836] Add missing scope Fixes ``` rspec ./spec/unit/authorization/index_overriding_spec.rb[1:1] ``` --- spec/unit/authorization/index_overriding_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/authorization/index_overriding_spec.rb b/spec/unit/authorization/index_overriding_spec.rb index c1b57678cac..ba399fe2cb1 100644 --- a/spec/unit/authorization/index_overriding_spec.rb +++ b/spec/unit/authorization/index_overriding_spec.rb @@ -5,7 +5,7 @@ controller.instance_eval do def index super do - render Dependency.rails.render_key => 'Rendered from passed block' + render ActiveAdmin::Dependency.rails.render_key => 'Rendered from passed block' return end end From 06ab2d35dd08590a414b47b10e8fbe249ba8ab93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 16 Feb 2017 21:15:58 -0200 Subject: [PATCH 0334/3836] Refactor common code to a helper method --- spec/requests/default_namespace_spec.rb | 20 ++++---------------- spec/support/active_admin_request_helpers.rb | 12 ++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/spec/requests/default_namespace_spec.rb b/spec/requests/default_namespace_spec.rb index fa1b4cc6d1e..c92f512528b 100644 --- a/spec/requests/default_namespace_spec.rb +++ b/spec/requests/default_namespace_spec.rb @@ -8,17 +8,11 @@ describe "with a #{value} default namespace" do - before(:all) do - @__original_application = ActiveAdmin.application + around(:all) do |example| application = ActiveAdmin::Application.new application.default_namespace = value - ActiveAdmin.application = application - load_defaults! - reload_routes! - end - after(:all) do - ActiveAdmin.application = @__original_application + with_temp_application(application) { example.call } end it "should generate a log out path" do @@ -35,17 +29,11 @@ describe "with a test default namespace" do - before(:all) do - @__original_application = ActiveAdmin.application + around(:all) do |example| application = ActiveAdmin::Application.new application.default_namespace = :test - ActiveAdmin.application = application - load_defaults! - reload_routes! - end - after(:all) do - ActiveAdmin.application = @__original_application + with_temp_application(application) { example.call } end it "should generate a log out path" do diff --git a/spec/support/active_admin_request_helpers.rb b/spec/support/active_admin_request_helpers.rb index 383f4bf26a8..f023da2cee2 100644 --- a/spec/support/active_admin_request_helpers.rb +++ b/spec/support/active_admin_request_helpers.rb @@ -24,4 +24,16 @@ def last_response @router = ::Rails.application.routes end end + + def with_temp_application(application) + original_application = ActiveAdmin.application + ActiveAdmin.application = application + load_defaults! + reload_routes! + + yield + + ensure + ActiveAdmin.application = original_application + end end From aca21fb8fe228adcdff3a6a45b19754118c0b33c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 18 Feb 2017 07:43:39 -0200 Subject: [PATCH 0335/3836] Remove unnecessary global scope constant --- .../authorization/controller_authorization_spec.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/spec/unit/authorization/controller_authorization_spec.rb b/spec/unit/authorization/controller_authorization_spec.rb index c014229a07f..eac3d60ee72 100644 --- a/spec/unit/authorization/controller_authorization_spec.rb +++ b/spec/unit/authorization/controller_authorization_spec.rb @@ -1,5 +1,4 @@ require 'rails_helper' -Auth = ActiveAdmin::Authorization RSpec.describe Admin::PostsController, "Controller Authorization", type: :controller do @@ -12,28 +11,33 @@ end it "should authorize the index action" do - expect(authorization).to receive(:authorized?).with(Auth::READ, Post).and_return true + expect(authorization).to receive(:authorized?).with(auth::READ, Post).and_return true get :index expect(response).to be_success end it "should authorize the new action" do - expect(authorization).to receive(:authorized?).with(Auth::CREATE, an_instance_of(Post)).and_return true + expect(authorization).to receive(:authorized?).with(auth::CREATE, an_instance_of(Post)).and_return true get :new expect(response).to be_success end it "should authorize the create action with the new resource" do - expect(authorization).to receive(:authorized?).with(Auth::CREATE, an_instance_of(Post)).and_return true + expect(authorization).to receive(:authorized?).with(auth::CREATE, an_instance_of(Post)).and_return true post :create expect(response).to redirect_to action: 'show', id: Post.last.id end it "should redirect when the user isn't authorized" do - expect(authorization).to receive(:authorized?).with(Auth::READ, Post).and_return false + expect(authorization).to receive(:authorized?).with(auth::READ, Post).and_return false get :index expect(response.body).to eq 'You are being redirected.' expect(response).to redirect_to '/admin' end + private + + def auth + ActiveAdmin::Authorization + end end From 1a864a44b59afcbcc2804cfa1a847fc7085afeb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 18 Feb 2017 16:44:59 -0200 Subject: [PATCH 0336/3836] Remove unnecessary hack in controller specs --- spec/unit/action_builder_spec.rb | 1 - spec/unit/resource_controller/sidebars_spec.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb index a1c0531ec8d..2b99133e5c6 100644 --- a/spec/unit/action_builder_spec.rb +++ b/spec/unit/action_builder_spec.rb @@ -2,7 +2,6 @@ RSpec.describe 'defining actions from registration blocks', type: :controller do let(:klass){ Admin::PostsController } - render_views # https://github.com/rspec/rspec-rails/issues/860 before do @controller = klass.new diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index 34616e64e06..c90b0ab9ee8 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -2,7 +2,6 @@ RSpec.describe ActiveAdmin::ResourceController::Sidebars, type: :controller do let(:klass){ Admin::PostsController } - render_views # https://github.com/rspec/rspec-rails/issues/860 before do @controller = klass.new From 9e6962d11364e827eb6861e960822a60494875c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 18 Feb 2017 16:47:20 -0200 Subject: [PATCH 0337/3836] Reset state before memory spec Fixes ``` rspec \ ./spec/requests/memory_spec.rb[1] \ ./spec/unit/authorization/controller_authorization_spec.rb[1:1] \ --seed 24032 ``` --- spec/requests/memory_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/requests/memory_spec.rb b/spec/requests/memory_spec.rb index 755d385b3fc..3170ff871c4 100644 --- a/spec/requests/memory_spec.rb +++ b/spec/requests/memory_spec.rb @@ -1,6 +1,10 @@ require 'rails_helper' RSpec.describe "Memory Leak", type: :request, if: RUBY_ENGINE == 'ruby' do + before do + load_defaults! + end + def count_instances_of(klass) ObjectSpace.each_object(klass) { } end From d518690217fbbfee95ecac4ba6a87c720f1f82a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 12 Feb 2017 14:36:51 -0200 Subject: [PATCH 0338/3836] Rework `auto_link` tests Previous tests used too much mocking and were order dependent. Fixes ``` rspec spec/unit/auto_link_spec.rb --seed 1234 ``` --- spec/unit/auto_link_spec.rb | 52 +++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/spec/unit/auto_link_spec.rb b/spec/unit/auto_link_spec.rb index aea58f60f03..13201fadf04 100644 --- a/spec/unit/auto_link_spec.rb +++ b/spec/unit/auto_link_spec.rb @@ -1,20 +1,24 @@ require 'rails_helper' -RSpec.describe "auto linking resources" do +RSpec.describe "auto linking resources", type: :view do include ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper include ActiveAdmin::ViewHelpers::AutoLinkHelper include ActiveAdmin::ViewHelpers::DisplayHelper include MethodOrProcHelper let(:active_admin_config) { double namespace: namespace } - let(:active_admin_namespace){ ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) } + let(:active_admin_namespace){ ActiveAdmin.application.namespace(:admin) } let(:post){ Post.create! title: "Hello World" } - def authorized?(*) - true + before do + allow(self).to receive(:authorized?).and_return(true) end context "when the resource is not registered" do + before do + load_resources {} + end + it "should return the display name of the object" do expect(auto_link(post)).to eq "Hello World" end @@ -22,39 +26,43 @@ def authorized?(*) context "when the resource is registered" do before do - active_admin_namespace.register Post + load_resources do + active_admin_namespace.register Post + end end + it "should return a link with the display name of the object" do - url_path = "/admin/posts/#{post.id}?locale=en" - expect(self).to receive(:url_options).and_return(locale: 'en') - expect(self).to receive(:url_for) { |url| url } - expect(self).to receive(:link_to).with "Hello World", url_path - auto_link(post) + expect(auto_link(post)).to \ + match(%r{Hello World}) end context "but the user doesn't have access" do + before do + allow(self).to receive(:authorized?).and_return(false) + end + it "should return the display name of the object" do - expect(self).to receive(:authorized?).twice.and_return(false) expect(auto_link(post)).to eq "Hello World" end end + end - context "but the show action is disabled" do - before do + context "when the resource is registered with the show action disabled" do + before do + load_resources do active_admin_namespace.register(Post) { actions :all, except: :show } end + end - it "should fallback to edit" do - url_path = "/admin/posts/#{post.id}/edit?locale=en" - expect(self).to receive(:url_options).and_return(locale: 'en') - expect(self).to receive(:url_for) { |url| url } - expect(self).to receive(:link_to).with "Hello World", url_path - auto_link(post) - end + it "should fallback to edit" do + expect(auto_link(post)).to \ + match(%r{Hello World}) end + end - context "but the show and edit actions are disabled" do - before do + context "when the resource is registered with the show & edit actions disabled" do + before do + load_resources do active_admin_namespace.register(Post) do actions :all, except: [:show, :edit] end From 18acc2404cbda0ac382a23150735b235fae8f81b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 12 Feb 2017 15:03:11 -0200 Subject: [PATCH 0339/3836] Fix translation leaks --- spec/unit/localizers/resource_localizer_spec.rb | 6 ++++-- spec/unit/views/components/table_for_spec.rb | 14 ++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/spec/unit/localizers/resource_localizer_spec.rb b/spec/unit/localizers/resource_localizer_spec.rb index 976ec437962..474e2e3d68f 100644 --- a/spec/unit/localizers/resource_localizer_spec.rb +++ b/spec/unit/localizers/resource_localizer_spec.rb @@ -23,8 +23,10 @@ end describe "model action specified" do - before do - I18n.backend.store_translations :en, active_admin: {resources: {comment: {new_model: 'Write comment'}}} + around do |example| + with_translation active_admin: {resources: {comment: {new_model: 'Write comment'}}} do + example.call + end end it_behaves_like "ActiveAdmin::Localizers::ResourceLocalizer" do diff --git a/spec/unit/views/components/table_for_spec.rb b/spec/unit/views/components/table_for_spec.rb index 59d6bc923c6..d5632f5bc18 100644 --- a/spec/unit/views/components/table_for_spec.rb +++ b/spec/unit/views/components/table_for_spec.rb @@ -308,9 +308,10 @@ end context "when i18n option is specified" do - before(:each) do - I18n.backend.store_translations :en, - activerecord: { attributes: { post: { title: "Name" } } } + around do |example| + with_translation(activerecord: { attributes: { post: { title: "Name" } } }) do + example.call + end end let(:table) do @@ -327,9 +328,10 @@ end context "when i18n option is not specified" do - before(:each) do - I18n.backend.store_translations :en, - activerecord: { attributes: { post: { title: "Name" } } } + around do |example| + with_translation(activerecord: { attributes: { post: { title: "Name" } } }) do + example.call + end end let(:collection) do From 35a7ee1042b3997e1d026c022c29d171759dbc43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 09:55:34 -0300 Subject: [PATCH 0340/3836] Remove unnecessary include --- spec/unit/views/tabbed_navigation_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/unit/views/tabbed_navigation_spec.rb b/spec/unit/views/tabbed_navigation_spec.rb index 355750284ac..22657e5c92c 100644 --- a/spec/unit/views/tabbed_navigation_spec.rb +++ b/spec/unit/views/tabbed_navigation_spec.rb @@ -1,6 +1,5 @@ require 'rails_helper' -include ActiveAdmin RSpec.describe ActiveAdmin::Views::TabbedNavigation do let(:menu){ ActiveAdmin::Menu.new } From 1ed550b3975757c8e83dfffbab06d6b64b33d01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 09:55:49 -0300 Subject: [PATCH 0341/3836] Register Post before specs using it Fixes ``` rspec \ ./spec/unit/auto_link_spec.rb[1:1:1] \ ./spec/unit/views/tabbed_navigation_spec.rb[1:1:4] \ --seed 4320 ``` --- spec/unit/views/tabbed_navigation_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/unit/views/tabbed_navigation_spec.rb b/spec/unit/views/tabbed_navigation_spec.rb index 22657e5c92c..bccd173f47b 100644 --- a/spec/unit/views/tabbed_navigation_spec.rb +++ b/spec/unit/views/tabbed_navigation_spec.rb @@ -16,6 +16,7 @@ let(:html) { Capybara.string(tabbed_navigation.to_s) } before do + load_resources { ActiveAdmin.register Post } allow(helpers).to receive(:admin_logged_in?).and_return(false) end From 3deb61ecaabc88e500a43992323cc11aab9744d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:17:12 -0300 Subject: [PATCH 0342/3836] Fix spec leaking comments order Fixes ``` rspec ./spec/unit/comments_spec.rb[1:1:2:4,1:1:2:5] --seed 43154 ``` --- spec/unit/comments_spec.rb | 43 ++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/spec/unit/comments_spec.rb b/spec/unit/comments_spec.rb index 5dc7ef190c9..b5e3fa47fb3 100644 --- a/spec/unit/comments_spec.rb +++ b/spec/unit/comments_spec.rb @@ -39,7 +39,7 @@ expect(ActiveAdmin::Comment.find_for_resource_in_namespace(another_post, namespace_name)).to eq [] end - it "should return the most recent comment first" do + it "should return the most recent comment first by default" do ActiveAdmin::Comment.class_eval { attr_accessible :created_at } if Rails::VERSION::MAJOR == 3 another_comment = ActiveAdmin::Comment.create! resource: post, body: "Another Comment", @@ -58,24 +58,31 @@ expect(comments.last).to eq(another_comment) end - it "should return the correctly ordered comments" do - ActiveAdmin::Application.inheritable_setting( - :comments_order, "created_at DESC" - ) + context "when custom ordering configured" do + around do |example| + previous_order = ActiveAdmin.application.comments_order + ActiveAdmin.application.comments_order = "created_at DESC" - another_comment = ActiveAdmin::Comment.create!( - resource: post, - body: "Another Comment", - namespace: namespace_name, - created_at: @comment.created_at + 20.minutes - ) - - comments = ActiveAdmin::Comment.find_for_resource_in_namespace( - post, namespace_name - ) - expect(comments.size).to eq 2 - expect(comments.first).to eq(another_comment) - expect(comments.last).to eq(@comment) + example.call + + ActiveAdmin.application.comments_order = previous_order + end + + it "should return the correctly ordered comments" do + another_comment = ActiveAdmin::Comment.create!( + resource: post, + body: "Another Comment", + namespace: namespace_name, + created_at: @comment.created_at + 20.minutes + ) + + comments = ActiveAdmin::Comment.find_for_resource_in_namespace( + post, namespace_name + ) + expect(comments.size).to eq 2 + expect(comments.first).to eq(another_comment) + expect(comments.last).to eq(@comment) + end end end From b0445292a791a215ce9406119aa0b5aebce8adfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:31:37 -0300 Subject: [PATCH 0343/3836] Normalize spec descriptions in an example group --- spec/unit/resource_controller/sidebars_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index c90b0ab9ee8..3f94699976f 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -7,7 +7,7 @@ @controller = klass.new end - context 'without before_filter' do + context 'without skip_sidebar! before filter' do before do ActiveAdmin.register Post reload_routes! @@ -20,7 +20,7 @@ end end - describe '#skip_sidebar!' do + context 'with skip_sidebar! before_filter' do before do ActiveAdmin.register Post do before_filter :skip_sidebar! From de19640cfcfcf321dbbd1ae1f7409ef66171031d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:34:54 -0300 Subject: [PATCH 0344/3836] Extract common setup to a shared context --- .../unit/resource_controller/sidebars_spec.rb | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index 3f94699976f..5fd565c3017 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -3,34 +3,35 @@ RSpec.describe ActiveAdmin::ResourceController::Sidebars, type: :controller do let(:klass){ Admin::PostsController } - before do - @controller = klass.new + shared_context 'with post config' do + before do + @controller = klass.new + + post_config + reload_routes! + + get :index + end end context 'without skip_sidebar! before filter' do - before do - ActiveAdmin.register Post - reload_routes! + include_context 'with post config' do + let(:post_config) { ActiveAdmin.register Post } end it 'does not set @skip_sidebar' do - get :index - expect(controller.instance_variable_get(:@skip_sidebar)).to eq nil end end context 'with skip_sidebar! before_filter' do - before do - ActiveAdmin.register Post do - before_filter :skip_sidebar! + include_context 'with post config' do + let(:post_config) do + ActiveAdmin.register(Post) { before_filter :skip_sidebar! } end - reload_routes! end it 'works' do - get :index - expect(controller.instance_variable_get(:@skip_sidebar)).to eq true end end From b51ca6ff949003d96cf61f99a3c8c769a1804112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:46:44 -0300 Subject: [PATCH 0345/3836] Fix action_controller configuration leak --- spec/unit/devise_spec.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/spec/unit/devise_spec.rb b/spec/unit/devise_spec.rb index f45bc1dbe33..b8e812fda6c 100644 --- a/spec/unit/devise_spec.rb +++ b/spec/unit/devise_spec.rb @@ -12,10 +12,22 @@ def self.helper(*); end end let(:controller) { controller_class.new } + let(:action_controller_config) { Rails.configuration.action_controller } + + def with_temp_relative_url_root(relative_url_root) + previous_relative_url_root = action_controller_config[:relative_url_root] + action_controller_config[:relative_url_root] = relative_url_root + + yield + ensure + action_controller_config[:relative_url_root] = previous_relative_url_root + end context 'with a RAILS_RELATIVE_URL_ROOT set' do - before { Rails.configuration.action_controller[:relative_url_root] = '/foo' } + around do |example| + with_temp_relative_url_root('/foo') { example.call } + end it "should set the root path to the default namespace" do expect(controller.root_path).to eq "/foo/admin" @@ -30,7 +42,9 @@ def self.helper(*); end context 'without a RAILS_RELATIVE_URL_ROOT set' do - before { Rails.configuration.action_controller[:relative_url_root] = nil } + around do |example| + with_temp_relative_url_root(nil) { example.call } + end it "should set the root path to the default namespace" do expect(controller.root_path).to eq "/admin" From 1602d5a2dee781a90cd382c656415bbb7c54d29e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:54:46 -0300 Subject: [PATCH 0346/3836] Load the resources the following specs need Fixes ``` rspec \ ./spec/unit/resource_controller/sidebars_spec.rb[1:1:1] \ ./spec/unit/view_helpers/display_helper_spec.rb[1:2:11] \ --seed 37254 `` --- spec/unit/view_helpers/display_helper_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/unit/view_helpers/display_helper_spec.rb b/spec/unit/view_helpers/display_helper_spec.rb index fca2b16f61f..721f6250c18 100644 --- a/spec/unit/view_helpers/display_helper_spec.rb +++ b/spec/unit/view_helpers/display_helper_spec.rb @@ -20,6 +20,13 @@ def url_options { locale: nil } end + before do + load_resources do + ActiveAdmin.register(User) + ActiveAdmin.register(Post){ belongs_to :user, optional: true } + end + end + describe '#display_name' do ActiveAdmin::Application.new.display_name_methods.map(&:to_s).each do |m| it "should return #{m} when defined" do From fd12472d2020f2c1ca0f486e43a35ec5abe98598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 11:10:39 -0300 Subject: [PATCH 0347/3836] Extract some `let`'s --- spec/unit/resource_controller_spec.rb | 4 +--- spec/unit/routing_spec.rb | 8 +++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/unit/resource_controller_spec.rb b/spec/unit/resource_controller_spec.rb index f7b52623b53..7b244a09fe0 100644 --- a/spec/unit/resource_controller_spec.rb +++ b/spec/unit/resource_controller_spec.rb @@ -156,9 +156,9 @@ def call_after_destroy(obj); end end RSpec.describe Admin::PostsController, type: "controller" do + let(:controller){ Admin::PostsController.new } describe 'retrieving the resource' do - let(:controller){ Admin::PostsController.new } let(:post) { Post.new title: "An incledibly unique Post Title" } before do @@ -187,7 +187,6 @@ def call_after_destroy(obj); end end describe 'retrieving the resource collection' do - let(:controller){ Admin::PostsController.new } let(:config) { controller.class.active_admin_config } before do Post.create!(title: "An incledibly unique Post Title") if Post.count == 0 @@ -223,7 +222,6 @@ def call_after_destroy(obj); end describe "performing batch_action" do - let(:controller){ Admin::PostsController.new } let(:batch_action) { ActiveAdmin::BatchAction.new :flag, "Flag", &batch_action_block } let(:batch_action_block) { proc { } } before do diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index b307cd05a7a..1f468765cf1 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -14,8 +14,10 @@ reload_routes! end + let(:namespaces) { ActiveAdmin.application.namespaces } + it "should only have the namespaces necessary for route testing" do - expect(ActiveAdmin.application.namespaces.names).to eq [:admin, :root] + expect(namespaces.names).to eq [:admin, :root] end it "should route to the admin dashboard" do @@ -33,12 +35,12 @@ describe "route_options" do context "with a custom path set in route_options" do before(:each) do - ActiveAdmin.application.namespaces[:admin].route_options = { path: '/custom-path' } + namespaces[:admin].route_options = { path: '/custom-path' } reload_routes! end after(:all) do - ActiveAdmin.application.namespaces[:admin].route_options = {} + namespaces[:admin].route_options = {} reload_routes! end From 1448cb60709a853dc9acb682953b0e944fd4e69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:36:12 -0300 Subject: [PATCH 0348/3836] Delay tested controller instantiations We need to make sure we instantiate the tested controller after we load the specific resource configuration we need. Otherwise, the controller might have a configuration leaked by previous specs. Fixes ``` rspec \ ./spec/unit/namespace/register_resource_spec.rb[1:5:4:1:1] \ ./spec/unit/resource_controller_spec.rb[2:1:1] \ --seed 1234 ``` ``` rspec ./spec/unit/resource_controller/sidebars_spec.rb ``` or ``` rspec \ ./spec/unit/authorization/controller_authorization_spec.rb[1:1] \ ./spec/unit/namespace/register_resource_spec.rb[1:5:4:1:1] \ --seed 7379 ``` and probably others. --- spec/unit/action_builder_spec.rb | 13 +++---------- .../authorization/controller_authorization_spec.rb | 6 +++--- spec/unit/authorization/index_overriding_spec.rb | 10 +++++----- spec/unit/resource_controller/sidebars_spec.rb | 4 ++-- spec/unit/resource_controller_spec.rb | 8 ++++++-- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb index 2b99133e5c6..be375eb2406 100644 --- a/spec/unit/action_builder_spec.rb +++ b/spec/unit/action_builder_spec.rb @@ -4,15 +4,13 @@ let(:klass){ Admin::PostsController } before do + action! + reload_routes! + @controller = klass.new end describe 'creates a member action' do - before do - action! - reload_routes! - end - after(:each) do klass.clear_member_actions! end @@ -71,11 +69,6 @@ end describe 'creates a collection action' do - before do - action! - reload_routes! - end - after(:each) do klass.clear_collection_actions! end diff --git a/spec/unit/authorization/controller_authorization_spec.rb b/spec/unit/authorization/controller_authorization_spec.rb index eac3d60ee72..9a7fcf67462 100644 --- a/spec/unit/authorization/controller_authorization_spec.rb +++ b/spec/unit/authorization/controller_authorization_spec.rb @@ -1,13 +1,13 @@ require 'rails_helper' -RSpec.describe Admin::PostsController, "Controller Authorization", type: :controller do +RSpec.describe "Controller Authorization", type: :controller do let(:authorization){ controller.send(:active_admin_authorization) } before do load_defaults! - # HACK: the AA config is missing, so we throw it in here - controller.class.active_admin_config = ActiveAdmin.application.namespace(:admin).resources['Post'].controller.active_admin_config + @controller = Admin::PostsController.new + allow(authorization).to receive(:authorized?) end it "should authorize the index action" do diff --git a/spec/unit/authorization/index_overriding_spec.rb b/spec/unit/authorization/index_overriding_spec.rb index ba399fe2cb1..217ec494c02 100644 --- a/spec/unit/authorization/index_overriding_spec.rb +++ b/spec/unit/authorization/index_overriding_spec.rb @@ -1,8 +1,11 @@ require 'rails_helper' -RSpec.describe Admin::PostsController, 'Index overriding', type: :controller do +RSpec.describe 'Index overriding', type: :controller do before do - controller.instance_eval do + load_defaults! + @controller = Admin::PostsController.new + + @controller.instance_eval do def index super do render ActiveAdmin::Dependency.rails.render_key => 'Rendered from passed block' @@ -10,9 +13,6 @@ def index end end end - load_defaults! - # HACK: the AA config is missing, so we throw it in here - controller.class.active_admin_config = ActiveAdmin.application.namespace(:admin).resources['Post'].controller.active_admin_config end it 'should call block passed to overridden index' do diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index 5fd565c3017..fd006b07c79 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -5,11 +5,11 @@ shared_context 'with post config' do before do - @controller = klass.new - post_config reload_routes! + @controller = klass.new + get :index end end diff --git a/spec/unit/resource_controller_spec.rb b/spec/unit/resource_controller_spec.rb index 7b244a09fe0..57734fb0ca0 100644 --- a/spec/unit/resource_controller_spec.rb +++ b/spec/unit/resource_controller_spec.rb @@ -155,8 +155,12 @@ def call_after_destroy(obj); end end end -RSpec.describe Admin::PostsController, type: "controller" do - let(:controller){ Admin::PostsController.new } +RSpec.describe "A specific resource controller", type: "controller" do + before do + load_resources { ActiveAdmin.register Post } + + @controller = Admin::PostsController.new + end describe 'retrieving the resource' do let(:post) { Post.new title: "An incledibly unique Post Title" } From 940e4242a249df132c595166d48e3f9dc021d6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 11:28:45 -0300 Subject: [PATCH 0349/3836] Remove unnecessary nesting --- spec/unit/resource/routes_spec.rb | 192 +++++++++++++++--------------- 1 file changed, 95 insertions(+), 97 deletions(-) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index abdd55a26c0..9ca0c976e64 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -1,141 +1,139 @@ require 'rails_helper' -module ActiveAdmin - RSpec.describe Resource::Routes do +RSpec.describe ActiveAdmin::Resource::Routes do - after do - load_defaults! - reload_routes! - end + after do + load_defaults! + reload_routes! + end - describe "route names" do - context "when in the admin namespace" do - let!(:config) { ActiveAdmin.register Category } - let(:category) { Category.new { |c| c.id = 123 } } + describe "route names" do + context "when in the admin namespace" do + let!(:config) { ActiveAdmin.register Category } + let(:category) { Category.new { |c| c.id = 123 } } - it "should return the route prefix" do - expect(config.route_prefix).to eq 'admin' - end + it "should return the route prefix" do + expect(config.route_prefix).to eq 'admin' + end - it "should return the route collection path" do - expect(config.route_collection_path).to eq '/admin/categories' - end + it "should return the route collection path" do + expect(config.route_collection_path).to eq '/admin/categories' + end - it "should return the route instance path" do - expect(config.route_instance_path(category)).to eq '/admin/categories/123' - end + it "should return the route instance path" do + expect(config.route_instance_path(category)).to eq '/admin/categories/123' end + end - context "when in the root namespace" do - let!(:config) { ActiveAdmin.register Category, namespace: false } - it "should have a nil route_prefix" do - expect(config.route_prefix).to eq nil - end + context "when in the root namespace" do + let!(:config) { ActiveAdmin.register Category, namespace: false } + it "should have a nil route_prefix" do + expect(config.route_prefix).to eq nil + end - it "should generate a correct route" do - reload_routes! - expect(config.route_collection_path).to eq "/categories" - end + it "should generate a correct route" do + reload_routes! + expect(config.route_collection_path).to eq "/categories" end + end - context "when registering a plural resource" do - class ::News; def self.has_many(*); end end - let!(:config) { ActiveAdmin.register News } - before{ reload_routes! } + context "when registering a plural resource" do + class ::News; def self.has_many(*); end end + let!(:config) { ActiveAdmin.register News } + before{ reload_routes! } - it "should return the plural route with _index" do - expect(config.route_collection_path).to eq "/admin/news" - end + it "should return the plural route with _index" do + expect(config.route_collection_path).to eq "/admin/news" end + end - context "when the resource belongs to another resource" do - let! :config do - ActiveAdmin.register Post do - belongs_to :category - end + context "when the resource belongs to another resource" do + let! :config do + ActiveAdmin.register Post do + belongs_to :category end + end - let :post do - Post.new do |p| - p.id = 3 - p.category = Category.new{ |c| c.id = 1 } - end + let :post do + Post.new do |p| + p.id = 3 + p.category = Category.new{ |c| c.id = 1 } end + end - before{ reload_routes! } + before{ reload_routes! } - it "should nest the collection path" do - expect(config.route_collection_path(category_id: 1)).to eq "/admin/categories/1/posts" - end + it "should nest the collection path" do + expect(config.route_collection_path(category_id: 1)).to eq "/admin/categories/1/posts" + end - it "should nest the instance path" do - expect(config.route_instance_path(post)).to eq "/admin/categories/1/posts/3" - end + it "should nest the instance path" do + expect(config.route_instance_path(post)).to eq "/admin/categories/1/posts/3" end + end - context "when the resources belongs to two other resources" do - let! :config do - ActiveAdmin.register Tagging do - belongs_to :category - belongs_to :post - end + context "when the resources belongs to two other resources" do + let! :config do + ActiveAdmin.register Tagging do + belongs_to :category + belongs_to :post end + end - let :tagging do - Tagging.new do |t| - t.id = 4 - t.post = Post.new do |p| - p.id = 3 - p.category = Category.new{ |c| c.id = 1 } - end + let :tagging do + Tagging.new do |t| + t.id = 4 + t.post = Post.new do |p| + p.id = 3 + p.category = Category.new{ |c| c.id = 1 } end end + end - before{ reload_routes! } + before{ reload_routes! } - it "should nest the collection path" do - expect(config.route_collection_path(category_id: 1, post_id: 3)).to eq "/admin/categories/1/posts/3/taggings" - end + it "should nest the collection path" do + expect(config.route_collection_path(category_id: 1, post_id: 3)).to eq "/admin/categories/1/posts/3/taggings" + end - it "should nest the instance path" do - expect(config.route_instance_path(tagging)).to eq "/admin/categories/1/posts/3/taggings/4" - end + it "should nest the instance path" do + expect(config.route_instance_path(tagging)).to eq "/admin/categories/1/posts/3/taggings/4" end + end - context "for batch_action handler" do - before do - config.batch_actions = true - reload_routes! - end + context "for batch_action handler" do + before do + config.batch_actions = true + reload_routes! + end - context "when register a singular resource" do + context "when register a singular resource" do - let! :config do - ActiveAdmin.register Post do - belongs_to :category - end + let! :config do + ActiveAdmin.register Post do + belongs_to :category end + end - it "should include :scope and :q params" do - params = { category_id: 1, q: { name_equals: "Any" }, scope: :all } - additional_params = { locale: 'en' } - batch_action_path = "/admin/categories/1/posts/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + it "should include :scope and :q params" do + params = { category_id: 1, q: { name_equals: "Any" }, scope: :all } + additional_params = { locale: 'en' } + batch_action_path = "/admin/categories/1/posts/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" - expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path - end + expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path end + end - context "when registering a plural resource" do + context "when registering a plural resource" do - class ::News; def self.has_many(*); end end - let!(:config) { ActiveAdmin.register News } + class ::News; def self.has_many(*); end end + let!(:config) { ActiveAdmin.register News } - it "should return the plural batch action route with _index and given params" do - params = { q: { name_equals: "Any" }, scope: :all } - additional_params = { locale: 'en' } - batch_action_path = "/admin/news/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" - expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path - end + it "should return the plural batch action route with _index and given params" do + params = { q: { name_equals: "Any" }, scope: :all } + additional_params = { locale: 'en' } + batch_action_path = "/admin/news/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path end end end From b680d0a8d3340d8f5d71ea86f86c422e077df0fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 11:30:43 -0300 Subject: [PATCH 0350/3836] Remove another unnecessary nesting --- spec/unit/resource/routes_spec.rb | 180 +++++++++++++++--------------- 1 file changed, 89 insertions(+), 91 deletions(-) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 9ca0c976e64..93bf4f871b2 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -7,134 +7,132 @@ reload_routes! end - describe "route names" do - context "when in the admin namespace" do - let!(:config) { ActiveAdmin.register Category } - let(:category) { Category.new { |c| c.id = 123 } } + context "when in the admin namespace" do + let!(:config) { ActiveAdmin.register Category } + let(:category) { Category.new { |c| c.id = 123 } } - it "should return the route prefix" do - expect(config.route_prefix).to eq 'admin' - end + it "should return the route prefix" do + expect(config.route_prefix).to eq 'admin' + end - it "should return the route collection path" do - expect(config.route_collection_path).to eq '/admin/categories' - end + it "should return the route collection path" do + expect(config.route_collection_path).to eq '/admin/categories' + end - it "should return the route instance path" do - expect(config.route_instance_path(category)).to eq '/admin/categories/123' - end + it "should return the route instance path" do + expect(config.route_instance_path(category)).to eq '/admin/categories/123' end + end - context "when in the root namespace" do - let!(:config) { ActiveAdmin.register Category, namespace: false } - it "should have a nil route_prefix" do - expect(config.route_prefix).to eq nil - end + context "when in the root namespace" do + let!(:config) { ActiveAdmin.register Category, namespace: false } + it "should have a nil route_prefix" do + expect(config.route_prefix).to eq nil + end - it "should generate a correct route" do - reload_routes! - expect(config.route_collection_path).to eq "/categories" - end + it "should generate a correct route" do + reload_routes! + expect(config.route_collection_path).to eq "/categories" end + end - context "when registering a plural resource" do - class ::News; def self.has_many(*); end end - let!(:config) { ActiveAdmin.register News } - before{ reload_routes! } + context "when registering a plural resource" do + class ::News; def self.has_many(*); end end + let!(:config) { ActiveAdmin.register News } + before{ reload_routes! } - it "should return the plural route with _index" do - expect(config.route_collection_path).to eq "/admin/news" - end + it "should return the plural route with _index" do + expect(config.route_collection_path).to eq "/admin/news" end + end - context "when the resource belongs to another resource" do - let! :config do - ActiveAdmin.register Post do - belongs_to :category - end + context "when the resource belongs to another resource" do + let! :config do + ActiveAdmin.register Post do + belongs_to :category end + end - let :post do - Post.new do |p| - p.id = 3 - p.category = Category.new{ |c| c.id = 1 } - end + let :post do + Post.new do |p| + p.id = 3 + p.category = Category.new{ |c| c.id = 1 } end + end - before{ reload_routes! } + before{ reload_routes! } - it "should nest the collection path" do - expect(config.route_collection_path(category_id: 1)).to eq "/admin/categories/1/posts" - end + it "should nest the collection path" do + expect(config.route_collection_path(category_id: 1)).to eq "/admin/categories/1/posts" + end - it "should nest the instance path" do - expect(config.route_instance_path(post)).to eq "/admin/categories/1/posts/3" - end + it "should nest the instance path" do + expect(config.route_instance_path(post)).to eq "/admin/categories/1/posts/3" end + end - context "when the resources belongs to two other resources" do - let! :config do - ActiveAdmin.register Tagging do - belongs_to :category - belongs_to :post - end + context "when the resources belongs to two other resources" do + let! :config do + ActiveAdmin.register Tagging do + belongs_to :category + belongs_to :post end + end - let :tagging do - Tagging.new do |t| - t.id = 4 - t.post = Post.new do |p| - p.id = 3 - p.category = Category.new{ |c| c.id = 1 } - end + let :tagging do + Tagging.new do |t| + t.id = 4 + t.post = Post.new do |p| + p.id = 3 + p.category = Category.new{ |c| c.id = 1 } end end + end - before{ reload_routes! } + before{ reload_routes! } - it "should nest the collection path" do - expect(config.route_collection_path(category_id: 1, post_id: 3)).to eq "/admin/categories/1/posts/3/taggings" - end + it "should nest the collection path" do + expect(config.route_collection_path(category_id: 1, post_id: 3)).to eq "/admin/categories/1/posts/3/taggings" + end - it "should nest the instance path" do - expect(config.route_instance_path(tagging)).to eq "/admin/categories/1/posts/3/taggings/4" - end + it "should nest the instance path" do + expect(config.route_instance_path(tagging)).to eq "/admin/categories/1/posts/3/taggings/4" end + end - context "for batch_action handler" do - before do - config.batch_actions = true - reload_routes! - end + context "for batch_action handler" do + before do + config.batch_actions = true + reload_routes! + end - context "when register a singular resource" do + context "when register a singular resource" do - let! :config do - ActiveAdmin.register Post do - belongs_to :category - end + let! :config do + ActiveAdmin.register Post do + belongs_to :category end + end - it "should include :scope and :q params" do - params = { category_id: 1, q: { name_equals: "Any" }, scope: :all } - additional_params = { locale: 'en' } - batch_action_path = "/admin/categories/1/posts/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + it "should include :scope and :q params" do + params = { category_id: 1, q: { name_equals: "Any" }, scope: :all } + additional_params = { locale: 'en' } + batch_action_path = "/admin/categories/1/posts/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" - expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path - end + expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path end + end - context "when registering a plural resource" do + context "when registering a plural resource" do - class ::News; def self.has_many(*); end end - let!(:config) { ActiveAdmin.register News } + class ::News; def self.has_many(*); end end + let!(:config) { ActiveAdmin.register News } - it "should return the plural batch action route with _index and given params" do - params = { q: { name_equals: "Any" }, scope: :all } - additional_params = { locale: 'en' } - batch_action_path = "/admin/news/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" - expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path - end + it "should return the plural batch action route with _index and given params" do + params = { q: { name_equals: "Any" }, scope: :all } + additional_params = { locale: 'en' } + batch_action_path = "/admin/news/batch_action?locale=en&q%5Bname_equals%5D=Any&scope=all" + expect(config.route_batch_action_path(params, additional_params)).to eq batch_action_path end end end From aa3bd9b323ccd1fb471f5a6bf86a3884a21bbf72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:07:21 -0300 Subject: [PATCH 0351/3836] Add missing state to routes spec Fixes ``` rspec \ ./spec/unit/authorization/controller_authorization_spec.rb[1:2] \ ./spec/unit/resource/routes_spec.rb[1:1:4:1] \ --seed 24919 ``` and ``` rspec \ ./spec/unit/resource/routes_spec.rb[1:5:1] \ ./spec/unit/resource_controller_spec.rb[2:2:3:1] \ --seed 56833 ``` --- spec/unit/resource/routes_spec.rb | 33 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 93bf4f871b2..4d6313264a8 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -7,6 +7,8 @@ reload_routes! end + let(:namespace) { ActiveAdmin.application.namespace(:admin) } + context "when in the admin namespace" do let!(:config) { ActiveAdmin.register Category } let(:category) { Category.new { |c| c.id = 123 } } @@ -47,11 +49,7 @@ class ::News; def self.has_many(*); end end end context "when the resource belongs to another resource" do - let! :config do - ActiveAdmin.register Post do - belongs_to :category - end - end + let(:config) { namespace.resource_for('Post') } let :post do Post.new do |p| @@ -60,7 +58,12 @@ class ::News; def self.has_many(*); end end end end - before{ reload_routes! } + before do + ActiveAdmin.register Category + ActiveAdmin.register(Post) { belongs_to :category } + + reload_routes! + end it "should nest the collection path" do expect(config.route_collection_path(category_id: 1)).to eq "/admin/categories/1/posts" @@ -72,12 +75,7 @@ class ::News; def self.has_many(*); end end end context "when the resources belongs to two other resources" do - let! :config do - ActiveAdmin.register Tagging do - belongs_to :category - belongs_to :post - end - end + let(:config) { namespace.resource_for('Tagging') } let :tagging do Tagging.new do |t| @@ -89,7 +87,16 @@ class ::News; def self.has_many(*); end end end end - before{ reload_routes! } + before do + ActiveAdmin.register Category + ActiveAdmin.register Post + ActiveAdmin.register Tagging do + belongs_to :category + belongs_to :post + end + + reload_routes! + end it "should nest the collection path" do expect(config.route_collection_path(category_id: 1, post_id: 3)).to eq "/admin/categories/1/posts/3/taggings" From 8ac9df8642c343d72d8b69a63d1071c03a07e730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 10:33:24 -0300 Subject: [PATCH 0352/3836] Prefer `load_resources` to register + reload --- spec/unit/action_builder_spec.rb | 3 +- spec/unit/resource/routes_spec.rb | 29 +++++++++---------- .../unit/resource_controller/sidebars_spec.rb | 3 +- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb index be375eb2406..ec2d1edaa2e 100644 --- a/spec/unit/action_builder_spec.rb +++ b/spec/unit/action_builder_spec.rb @@ -4,8 +4,7 @@ let(:klass){ Admin::PostsController } before do - action! - reload_routes! + load_resources { action! } @controller = klass.new end diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 4d6313264a8..15f2e754784 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -59,10 +59,10 @@ class ::News; def self.has_many(*); end end end before do - ActiveAdmin.register Category - ActiveAdmin.register(Post) { belongs_to :category } - - reload_routes! + load_resources do + ActiveAdmin.register Category + ActiveAdmin.register(Post) { belongs_to :category } + end end it "should nest the collection path" do @@ -88,14 +88,14 @@ class ::News; def self.has_many(*); end end end before do - ActiveAdmin.register Category - ActiveAdmin.register Post - ActiveAdmin.register Tagging do - belongs_to :category - belongs_to :post + load_resources do + ActiveAdmin.register Category + ActiveAdmin.register Post + ActiveAdmin.register Tagging do + belongs_to :category + belongs_to :post + end end - - reload_routes! end it "should nest the collection path" do @@ -109,13 +109,12 @@ class ::News; def self.has_many(*); end end context "for batch_action handler" do before do - config.batch_actions = true - reload_routes! + load_resources { config.batch_actions = true } end context "when register a singular resource" do - let! :config do + let :config do ActiveAdmin.register Post do belongs_to :category end @@ -133,7 +132,7 @@ class ::News; def self.has_many(*); end end context "when registering a plural resource" do class ::News; def self.has_many(*); end end - let!(:config) { ActiveAdmin.register News } + let(:config) { ActiveAdmin.register News } it "should return the plural batch action route with _index and given params" do params = { q: { name_equals: "Any" }, scope: :all } diff --git a/spec/unit/resource_controller/sidebars_spec.rb b/spec/unit/resource_controller/sidebars_spec.rb index fd006b07c79..e84fe7f5f45 100644 --- a/spec/unit/resource_controller/sidebars_spec.rb +++ b/spec/unit/resource_controller/sidebars_spec.rb @@ -5,8 +5,7 @@ shared_context 'with post config' do before do - post_config - reload_routes! + load_resources { post_config } @controller = klass.new From 7cfc7d0e0decd9d9c903fede7baeb5c8b6dac8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 11:15:24 -0300 Subject: [PATCH 0353/3836] Normalize style for spec type specification Prefer symbols. --- spec/unit/resource_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/resource_controller_spec.rb b/spec/unit/resource_controller_spec.rb index 57734fb0ca0..cf4d1ac7240 100644 --- a/spec/unit/resource_controller_spec.rb +++ b/spec/unit/resource_controller_spec.rb @@ -155,7 +155,7 @@ def call_after_destroy(obj); end end end -RSpec.describe "A specific resource controller", type: "controller" do +RSpec.describe "A specific resource controller", type: :controller do before do load_resources { ActiveAdmin.register Post } From 8e02d2dc2203a6cb61e13ce222a377f5f02ec326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 11:24:16 -0300 Subject: [PATCH 0354/3836] Fixes several errors I run into while bisecting For example ``` ./spec/unit/auto_link_spec.rb:4:in `block in ': uninitialized constant ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper (NameError) ``` or ``` ./lib/active_admin/views/components/paginated_collection.rb:118:in `': uninitialized constant ActiveAdmin::ViewHelpers::DownloadFormatLinksHelper (NameError) ``` --- lib/active_admin/views/components/paginated_collection.rb | 1 + spec/unit/auto_link_spec.rb | 4 ++++ spec/unit/pretty_format_spec.rb | 1 + spec/unit/view_helpers/display_helper_spec.rb | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/lib/active_admin/views/components/paginated_collection.rb b/lib/active_admin/views/components/paginated_collection.rb index b7f66d7ff3a..87b52e28742 100644 --- a/lib/active_admin/views/components/paginated_collection.rb +++ b/lib/active_admin/views/components/paginated_collection.rb @@ -1,4 +1,5 @@ require 'active_admin/helpers/collection' +require 'active_admin/view_helpers/download_format_links_helper' module ActiveAdmin module Views diff --git a/spec/unit/auto_link_spec.rb b/spec/unit/auto_link_spec.rb index 13201fadf04..7f7168a0153 100644 --- a/spec/unit/auto_link_spec.rb +++ b/spec/unit/auto_link_spec.rb @@ -1,4 +1,8 @@ require 'rails_helper' +require 'active_admin/view_helpers/active_admin_application_helper' +require 'active_admin/view_helpers/auto_link_helper' +require 'active_admin/view_helpers/display_helper' +require 'active_admin/view_helpers/method_or_proc_helper' RSpec.describe "auto linking resources", type: :view do include ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper diff --git a/spec/unit/pretty_format_spec.rb b/spec/unit/pretty_format_spec.rb index de263ac2bde..3ac5020819f 100644 --- a/spec/unit/pretty_format_spec.rb +++ b/spec/unit/pretty_format_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'active_admin/view_helpers/display_helper' RSpec.describe "#pretty_format" do include ActiveAdmin::ViewHelpers::DisplayHelper diff --git a/spec/unit/view_helpers/display_helper_spec.rb b/spec/unit/view_helpers/display_helper_spec.rb index 721f6250c18..99cf718a70a 100644 --- a/spec/unit/view_helpers/display_helper_spec.rb +++ b/spec/unit/view_helpers/display_helper_spec.rb @@ -1,4 +1,8 @@ require 'rails_helper' +require 'active_admin/view_helpers/active_admin_application_helper' +require 'active_admin/view_helpers/auto_link_helper' +require 'active_admin/view_helpers/display_helper' +require 'active_admin/view_helpers/method_or_proc_helper' RSpec.describe ActiveAdmin::ViewHelpers::DisplayHelper do include ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper From 3e782935fb5dd8464a768ed29443ee8bfcef12a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 11:35:12 -0300 Subject: [PATCH 0355/3836] Reload routes after configuring resource Fixes ``` rspec \ ./spec/unit/authorization/index_overriding_spec.rb[1:1] \ ./spec/unit/resource/routes_spec.rb[1:1:3] \ --seed 50491 ``` --- spec/unit/resource/routes_spec.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 15f2e754784..2a037bd9b11 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -10,7 +10,12 @@ let(:namespace) { ActiveAdmin.application.namespace(:admin) } context "when in the admin namespace" do - let!(:config) { ActiveAdmin.register Category } + let(:config) { namespace.resource_for('Category') } + + before do + load_resources { ActiveAdmin.register Category } + end + let(:category) { Category.new { |c| c.id = 123 } } it "should return the route prefix" do From a7428c076bffb7980b8dcb71f80efe02ee4e63fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 11:47:39 -0300 Subject: [PATCH 0356/3836] Ensure both resources are loaded for all specs Fixes ``` rspec \ ./spec/unit/belongs_to_spec.rb[1:4:1] \ ./spec/unit/namespace/register_resource_spec.rb[1:5:4:1:1] \ --seed 43047 ``` --- spec/unit/belongs_to_spec.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/unit/belongs_to_spec.rb b/spec/unit/belongs_to_spec.rb index 611bf650b8f..749d3462b69 100644 --- a/spec/unit/belongs_to_spec.rb +++ b/spec/unit/belongs_to_spec.rb @@ -1,9 +1,17 @@ require 'rails_helper' RSpec.describe ActiveAdmin::Resource::BelongsTo do + before do + load_resources do + ActiveAdmin.register User + ActiveAdmin.register Post do belongs_to :user end + end + end + + let(:namespace) { ActiveAdmin.application.namespace(:admin) } - let(:user_config){ ActiveAdmin.register User } - let(:post_config){ ActiveAdmin.register Post do belongs_to :user end } + let(:user_config){ namespace.resource_for('User') } + let(:post_config){ namespace.resource_for('Post') } let(:belongs_to){ post_config.belongs_to_config.first } it "should have an owner" do From 98361d6a93681722af8504a31d93af5c198967b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 12:30:24 -0300 Subject: [PATCH 0357/3836] Reset root_options every time --- spec/unit/routing_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index 1f468765cf1..4a4e15f36ab 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -34,12 +34,12 @@ describe "route_options" do context "with a custom path set in route_options" do - before(:each) do + before do namespaces[:admin].route_options = { path: '/custom-path' } reload_routes! end - after(:all) do + after do namespaces[:admin].route_options = {} reload_routes! end From 8d3fc87ed37d3c983a2b7d4e17b5e3d4938f2a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 12:16:42 -0300 Subject: [PATCH 0358/3836] Don't leak the root namespace --- spec/unit/resource/routes_spec.rb | 8 +++++++- spec/unit/routing_spec.rb | 10 +++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 2a037bd9b11..b220492a4bf 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -7,7 +7,8 @@ reload_routes! end - let(:namespace) { ActiveAdmin.application.namespace(:admin) } + let(:application) { ActiveAdmin.application } + let(:namespace) { application.namespace(:admin) } context "when in the admin namespace" do let(:config) { namespace.resource_for('Category') } @@ -33,6 +34,11 @@ context "when in the root namespace" do let!(:config) { ActiveAdmin.register Category, namespace: false } + + after(:each) do + application.namespaces.instance_variable_get(:@namespaces).delete(:root) + end + it "should have a nil route_prefix" do expect(config.route_prefix).to eq nil end diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index 4a4e15f36ab..6343274765b 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -17,7 +17,7 @@ let(:namespaces) { ActiveAdmin.application.namespaces } it "should only have the namespaces necessary for route testing" do - expect(namespaces.names).to eq [:admin, :root] + expect(namespaces.names).to eq [:admin] end it "should route to the admin dashboard" do @@ -74,6 +74,10 @@ load_resources { ActiveAdmin.register(Post, namespace: false) } end + after(:each) do + namespaces.instance_variable_get(:@namespaces).delete(:root) + end + it "should route the index path" do expect(posts_path).to eq "/posts" end @@ -212,6 +216,10 @@ load_resources { ActiveAdmin.register_page("Chocolate I lØve You!", namespace: false) } end + after(:each) do + namespaces.instance_variable_get(:@namespaces).delete(:root) + end + it "should route to page under /" do expect(chocolate_i_love_you_path).to eq "/chocolate_i_love_you" end From d232ed115c0a1ee13f0f4a84eae2f1bfced370f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 09:41:45 -0300 Subject: [PATCH 0359/3836] Enable random ordering in tests by default --- spec/rails_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 7ae1d3557c9..38836f634e8 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -109,6 +109,7 @@ def with_translation(translation) config.filter_run_excluding skip: true config.run_all_when_everything_filtered = true config.color = true + config.order = :random devise = ActiveAdmin::Dependency.devise >= '4.2' ? Devise::Test::ControllerHelpers : Devise::TestHelpers config.include devise, type: :controller From 1d05eb485744cd0df1f1601858aa73619eeb58f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 13:11:02 -0300 Subject: [PATCH 0360/3836] Don't use before/after(:all) They lead to leaking state very easily. --- spec/unit/helpers/collection_spec.rb | 4 ++-- spec/unit/pretty_format_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/unit/helpers/collection_spec.rb b/spec/unit/helpers/collection_spec.rb index 90f1ed53d70..c8b146fce9f 100644 --- a/spec/unit/helpers/collection_spec.rb +++ b/spec/unit/helpers/collection_spec.rb @@ -4,14 +4,14 @@ include ActiveAdmin::Helpers::Collection - before(:all) do + before do Post.delete_all Post.create!(title: "A post") Post.create!(title: "A post") Post.create!(title: "An other post") end - after(:all) do + after do Post.delete_all end diff --git a/spec/unit/pretty_format_spec.rb b/spec/unit/pretty_format_spec.rb index 3ac5020819f..80046b68ebe 100644 --- a/spec/unit/pretty_format_spec.rb +++ b/spec/unit/pretty_format_spec.rb @@ -45,11 +45,11 @@ def method_missing(*args, &block) end context "with non-English locale" do - before(:all) do + before do @previous_locale = I18n.locale.to_s I18n.locale = "es" end - after(:all) do + after do I18n.locale = @previous_locale end it "should return a localized Date or Time with long format for non-english locale" do From 27dd3c226d82cb309e2f590edf34b64f65ecb884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 19 Feb 2017 13:11:46 -0300 Subject: [PATCH 0361/3836] Let transactions do their job --- spec/unit/helpers/collection_spec.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/spec/unit/helpers/collection_spec.rb b/spec/unit/helpers/collection_spec.rb index c8b146fce9f..4554ba991c6 100644 --- a/spec/unit/helpers/collection_spec.rb +++ b/spec/unit/helpers/collection_spec.rb @@ -5,16 +5,11 @@ include ActiveAdmin::Helpers::Collection before do - Post.delete_all Post.create!(title: "A post") Post.create!(title: "A post") Post.create!(title: "An other post") end - after do - Post.delete_all - end - describe "#collection_size" do it "should return the collection size for an ActiveRecord class" do expect(collection_size(Post.where(nil))).to eq 3 From 47289d1bdb13820252649d6cd5f4c88a1d83d503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Feb 2017 09:20:25 -0300 Subject: [PATCH 0362/3836] Load only what's needed for the specs to pass --- spec/unit/authorization/controller_authorization_spec.rb | 2 +- spec/unit/authorization/index_overriding_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/authorization/controller_authorization_spec.rb b/spec/unit/authorization/controller_authorization_spec.rb index 9a7fcf67462..d0d65fa2e8b 100644 --- a/spec/unit/authorization/controller_authorization_spec.rb +++ b/spec/unit/authorization/controller_authorization_spec.rb @@ -5,7 +5,7 @@ let(:authorization){ controller.send(:active_admin_authorization) } before do - load_defaults! + load_resources { ActiveAdmin.register Post } @controller = Admin::PostsController.new allow(authorization).to receive(:authorized?) end diff --git a/spec/unit/authorization/index_overriding_spec.rb b/spec/unit/authorization/index_overriding_spec.rb index 217ec494c02..2870b34162a 100644 --- a/spec/unit/authorization/index_overriding_spec.rb +++ b/spec/unit/authorization/index_overriding_spec.rb @@ -2,7 +2,7 @@ RSpec.describe 'Index overriding', type: :controller do before do - load_defaults! + load_resources { ActiveAdmin.register Post } @controller = Admin::PostsController.new @controller.instance_eval do From 2516871a914da9d03d64f715957f8d87d80a581e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Feb 2017 11:49:09 -0300 Subject: [PATCH 0363/3836] Ensure necessary resource is registered Fixes ``` rspec \ ./spec/unit/belongs_to_spec.rb[1:2:2:1] \ ./spec/unit/resource/routes_spec.rb[1:6:1:1] \ --seed 60387 ``` --- spec/unit/resource/routes_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index b220492a4bf..8881ace3891 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -126,6 +126,7 @@ class ::News; def self.has_many(*); end end context "when register a singular resource" do let :config do + ActiveAdmin.register Category ActiveAdmin.register Post do belongs_to :category end From 581255b65b194072cc63d2a91522942264375f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Feb 2017 13:07:30 -0300 Subject: [PATCH 0364/3836] Move class definition to the only file using it --- spec/rails_helper.rb | 4 ---- spec/unit/resource_spec.rb | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 38836f634e8..1777b642aae 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -55,10 +55,6 @@ def mock_action_view(assigns = {}) end alias_method :action_view, :mock_action_view - # A mock resource to register - class MockResource - end - def with_translation(translation) I18n.backend.store_translations :en, translation yield diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index d641457b4a1..f189a056595 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -148,6 +148,8 @@ def config(options = {}) describe "sort order" do + class MockResource + end context "when resource class responds to primary_key" do it "should sort by primary key desc by default" do From 85065fa2ef85f7fe8a8e0404ece2349d9ce91e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Feb 2017 12:57:07 -0300 Subject: [PATCH 0365/3836] Extract helper module to separate file And properly include it. --- spec/rails_helper.rb | 77 +++---------------- .../active_admin_integration_spec_helper.rb | 62 +++++++++++++++ 2 files changed, 71 insertions(+), 68 deletions(-) create mode 100644 spec/support/active_admin_integration_spec_helper.rb diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 1777b642aae..80eee8316e6 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,68 +1,5 @@ require 'spec_helper' -module ActiveAdminIntegrationSpecHelper - extend self - - def load_defaults! - ActiveAdmin.unload! - ActiveAdmin.load! - ActiveAdmin.register(Category) - ActiveAdmin.register(User) - ActiveAdmin.register(Post){ belongs_to :user, optional: true } - reload_menus! - end - - def reload_menus! - ActiveAdmin.application.namespaces.each{|n| n.reset_menu! } - end - - # Sometimes we need to reload the routes within - # the application to test them out - def reload_routes! - Rails.application.reload_routes! - end - - # Helper method to load resources and ensure that Active Admin is - # setup with the new configurations. - # - # Eg: - # load_resources do - # ActiveAdmin.register(Post) - # end - # - def load_resources - ActiveAdmin.unload! - yield - reload_menus! - reload_routes! - end - - def arbre(assigns = {}, helpers = mock_action_view, &block) - Arbre::Context.new(assigns, helpers, &block) - end - - def render_arbre_component(assigns = {}, helpers = mock_action_view, &block) - arbre(assigns, helpers, &block).children.first - end - - # Returns a fake action view instance to use with our renderers - def mock_action_view(assigns = {}) - controller = ActionView::TestCase::TestController.new - ActionView::Base.send :include, ActionView::Helpers - ActionView::Base.send :include, ActiveAdmin::ViewHelpers - ActionView::Base.send :include, Rails.application.routes.url_helpers - ActionView::Base.new(ActionController::Base.view_paths, assigns, controller) - end - alias_method :action_view, :mock_action_view - - def with_translation(translation) - I18n.backend.store_translations :en, translation - yield - ensure - I18n.backend.reload! - end -end - ENV['RAILS_ENV'] = 'test' require 'rails' @@ -86,11 +23,6 @@ def with_translation(translation) # JRuby Test::Unit.run = true if defined?(Test::Unit) && Test::Unit.respond_to?(:run=) -# Setup Some Admin stuff for us to play with -include ActiveAdminIntegrationSpecHelper -load_defaults! -reload_routes! - # Disabling authentication in specs so that we don't have to worry about # it allover the place ActiveAdmin.application.authentication_method = false @@ -110,8 +42,17 @@ def with_translation(translation) devise = ActiveAdmin::Dependency.devise >= '4.2' ? Devise::Test::ControllerHelpers : Devise::TestHelpers config.include devise, type: :controller + require 'support/active_admin_integration_spec_helper' + config.include ActiveAdminIntegrationSpecHelper + require 'support/active_admin_request_helpers' config.include ActiveAdminRequestHelpers, type: :request + + # Setup Some Admin stuff for us to play with + config.before(:suite) do + ActiveAdminIntegrationSpecHelper.load_defaults! + ActiveAdminIntegrationSpecHelper.reload_routes! + end end # Force deprecations to raise an exception. diff --git a/spec/support/active_admin_integration_spec_helper.rb b/spec/support/active_admin_integration_spec_helper.rb new file mode 100644 index 00000000000..9569f572e8e --- /dev/null +++ b/spec/support/active_admin_integration_spec_helper.rb @@ -0,0 +1,62 @@ +module ActiveAdminIntegrationSpecHelper + extend self + + def load_defaults! + ActiveAdmin.unload! + ActiveAdmin.load! + ActiveAdmin.register(Category) + ActiveAdmin.register(User) + ActiveAdmin.register(Post){ belongs_to :user, optional: true } + reload_menus! + end + + def reload_menus! + ActiveAdmin.application.namespaces.each{|n| n.reset_menu! } + end + + # Sometimes we need to reload the routes within + # the application to test them out + def reload_routes! + Rails.application.reload_routes! + end + + # Helper method to load resources and ensure that Active Admin is + # setup with the new configurations. + # + # Eg: + # load_resources do + # ActiveAdmin.register(Post) + # end + # + def load_resources + ActiveAdmin.unload! + yield + reload_menus! + reload_routes! + end + + def arbre(assigns = {}, helpers = mock_action_view, &block) + Arbre::Context.new(assigns, helpers, &block) + end + + def render_arbre_component(assigns = {}, helpers = mock_action_view, &block) + arbre(assigns, helpers, &block).children.first + end + + # Returns a fake action view instance to use with our renderers + def mock_action_view(assigns = {}) + controller = ActionView::TestCase::TestController.new + ActionView::Base.send :include, ActionView::Helpers + ActionView::Base.send :include, ActiveAdmin::ViewHelpers + ActionView::Base.send :include, Rails.application.routes.url_helpers + ActionView::Base.new(ActionController::Base.view_paths, assigns, controller) + end + alias_method :action_view, :mock_action_view + + def with_translation(translation) + I18n.backend.store_translations :en, translation + yield + ensure + I18n.backend.reload! + end +end From 788c6e9f4a8d84b704e4cc31b1c7f9852fd6b3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Feb 2017 13:10:52 -0300 Subject: [PATCH 0366/3836] Don't monkeypatch ActionView::Base Extend it instead. Fixes ``` rspec \ ./spec/unit/authorization/controller_authorization_spec.rb[1:2] \ ./spec/unit/views/components/index_list_spec.rb[1:1:1:1] \ --seed 42890 ``` --- spec/support/active_admin_integration_spec_helper.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spec/support/active_admin_integration_spec_helper.rb b/spec/support/active_admin_integration_spec_helper.rb index 9569f572e8e..c8977e5c19f 100644 --- a/spec/support/active_admin_integration_spec_helper.rb +++ b/spec/support/active_admin_integration_spec_helper.rb @@ -46,13 +46,17 @@ def render_arbre_component(assigns = {}, helpers = mock_action_view, &block) # Returns a fake action view instance to use with our renderers def mock_action_view(assigns = {}) controller = ActionView::TestCase::TestController.new - ActionView::Base.send :include, ActionView::Helpers - ActionView::Base.send :include, ActiveAdmin::ViewHelpers - ActionView::Base.send :include, Rails.application.routes.url_helpers - ActionView::Base.new(ActionController::Base.view_paths, assigns, controller) + MockActionView.new(ActionController::Base.view_paths, assigns, controller) end alias_method :action_view, :mock_action_view + # A mock action view to test view helpers + class MockActionView < ::ActionView::Base + include ActionView::Helpers + include ActiveAdmin::ViewHelpers + include Rails.application.routes.url_helpers + end + def with_translation(translation) I18n.backend.store_translations :en, translation yield From 6f74a0de798ceea54a9bfb6554df856e66535c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Feb 2017 14:55:05 -0300 Subject: [PATCH 0367/3836] Ensure resource controller is defined Fixes ``` rspec \ ./spec/unit/auto_link_spec.rb[1:1:1] \ ./spec/unit/dsl_spec.rb[1:4:2] \ --seed 11315 ``` --- spec/unit/dsl_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/dsl_spec.rb b/spec/unit/dsl_spec.rb index 1f79cee384d..761506a074c 100644 --- a/spec/unit/dsl_spec.rb +++ b/spec/unit/dsl_spec.rb @@ -10,7 +10,7 @@ def self.included(dsl) let(:application) { ActiveAdmin::Application.new } let(:namespace) { ActiveAdmin::Namespace.new application, :admin } - let(:resource_config) { ActiveAdmin::Resource.new namespace, Post } + let(:resource_config) { namespace.register Post } let(:dsl){ ActiveAdmin::DSL.new(resource_config) } describe "#include" do From a46c4654c0db561646a2468c586adcdf20cc9904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 20 Feb 2017 15:01:14 -0300 Subject: [PATCH 0368/3836] Ensure necessary resource for the specs is loaded Fixes ``` rspec \ ./spec/unit/auto_link_spec.rb[1:1:1] \ ./spec/unit/resource_controller/data_access_spec.rb[1:5:1] \ --seed 12654 ``` --- spec/unit/resource_controller/data_access_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/unit/resource_controller/data_access_spec.rb b/spec/unit/resource_controller/data_access_spec.rb index c2b64292029..bef1f22f3dc 100644 --- a/spec/unit/resource_controller/data_access_spec.rb +++ b/spec/unit/resource_controller/data_access_spec.rb @@ -1,6 +1,10 @@ require 'rails_helper' RSpec.describe ActiveAdmin::ResourceController::DataAccess do + before do + load_resources { ActiveAdmin.register Post } + end + let(:params) do {} end From 5bce88381c9793eb0581c44c387b0ab59eada52f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 21 Feb 2017 09:29:49 -0300 Subject: [PATCH 0369/3836] Remove let variable that's always overwritten --- spec/unit/resource_controller_spec.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/spec/unit/resource_controller_spec.rb b/spec/unit/resource_controller_spec.rb index cf4d1ac7240..8bd02e6ec27 100644 --- a/spec/unit/resource_controller_spec.rb +++ b/spec/unit/resource_controller_spec.rb @@ -2,11 +2,9 @@ RSpec.describe ActiveAdmin::ResourceController do - let(:controller) { ActiveAdmin::ResourceController.new } + let(:controller) { Admin::PostsController.new } describe "authenticating the user" do - let(:controller){ Admin::PostsController.new } - it "should do nothing when no authentication_method set" do namespace = controller.class.active_admin_config.namespace expect(namespace).to receive(:authentication_method).once.and_return(nil) @@ -28,8 +26,6 @@ end describe "retrieving the current user" do - let(:controller){ Admin::PostsController.new } - it "should return nil when no current_user_method set" do namespace = controller.class.active_admin_config.namespace expect(namespace).to receive(:current_user_method).once.and_return(nil) @@ -81,7 +77,6 @@ def call_after_destroy(obj); end end describe "performing create" do - let(:controller){ Admin::PostsController.new } let(:resource){ double("Resource", save: true) } before do @@ -107,7 +102,6 @@ def call_after_destroy(obj); end end describe "performing update" do - let(:controller){ Admin::PostsController.new } let(:resource){ double("Resource", :attributes= => true, save: true) } let(:attributes){ [{}] } @@ -135,7 +129,6 @@ def call_after_destroy(obj); end end describe "performing destroy" do - let(:controller){ Admin::PostsController.new } let(:resource){ double("Resource", destroy: true) } before do From 1dddda4913bd607e2f0d14e5706daf0b030e321b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 21 Feb 2017 10:14:05 -0300 Subject: [PATCH 0370/3836] Move specs to the example group with correct setup Fixes ``` rspec \ ./spec/unit/auto_link_spec.rb[1:1:1] \ ./spec/unit/resource_controller_spec.rb[1:2:2] \ --seed 45595 ``` --- spec/unit/resource_controller_spec.rb | 85 +++++++++++++-------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/spec/unit/resource_controller_spec.rb b/spec/unit/resource_controller_spec.rb index 8bd02e6ec27..718bc4bd1eb 100644 --- a/spec/unit/resource_controller_spec.rb +++ b/spec/unit/resource_controller_spec.rb @@ -4,49 +4,6 @@ let(:controller) { Admin::PostsController.new } - describe "authenticating the user" do - it "should do nothing when no authentication_method set" do - namespace = controller.class.active_admin_config.namespace - expect(namespace).to receive(:authentication_method).once.and_return(nil) - - controller.send(:authenticate_active_admin_user) - end - - it "should call the authentication_method when set" do - namespace = controller.class.active_admin_config.namespace - - expect(namespace).to receive(:authentication_method).twice. - and_return(:authenticate_admin_user!) - - expect(controller).to receive(:authenticate_admin_user!).and_return(true) - - controller.send(:authenticate_active_admin_user) - end - - end - - describe "retrieving the current user" do - it "should return nil when no current_user_method set" do - namespace = controller.class.active_admin_config.namespace - expect(namespace).to receive(:current_user_method).once.and_return(nil) - - expect(controller.send(:current_active_admin_user)).to eq nil - end - - it "should call the current_user_method when set" do - user = double - namespace = controller.class.active_admin_config.namespace - - expect(namespace).to receive(:current_user_method).twice. - and_return(:current_admin_user) - - expect(controller).to receive(:current_admin_user).and_return(user) - - expect(controller.send(:current_active_admin_user)).to eq user - end - end - - describe "callbacks" do before :all do application = ::ActiveAdmin::Application.new @@ -155,6 +112,48 @@ def call_after_destroy(obj); end @controller = Admin::PostsController.new end + describe "authenticating the user" do + it "should do nothing when no authentication_method set" do + namespace = controller.class.active_admin_config.namespace + expect(namespace).to receive(:authentication_method).once.and_return(nil) + + controller.send(:authenticate_active_admin_user) + end + + it "should call the authentication_method when set" do + namespace = controller.class.active_admin_config.namespace + + expect(namespace).to receive(:authentication_method).twice. + and_return(:authenticate_admin_user!) + + expect(controller).to receive(:authenticate_admin_user!).and_return(true) + + controller.send(:authenticate_active_admin_user) + end + + end + + describe "retrieving the current user" do + it "should return nil when no current_user_method set" do + namespace = controller.class.active_admin_config.namespace + expect(namespace).to receive(:current_user_method).once.and_return(nil) + + expect(controller.send(:current_active_admin_user)).to eq nil + end + + it "should call the current_user_method when set" do + user = double + namespace = controller.class.active_admin_config.namespace + + expect(namespace).to receive(:current_user_method).twice. + and_return(:current_admin_user) + + expect(controller).to receive(:current_admin_user).and_return(user) + + expect(controller.send(:current_active_admin_user)).to eq user + end + end + describe 'retrieving the resource' do let(:post) { Post.new title: "An incledibly unique Post Title" } From 45a51dac1a48dbf361a1de6bbcd4f224abe7e63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 21 Feb 2017 10:45:24 -0300 Subject: [PATCH 0371/3836] Separate tests for locale in `auto_link` --- spec/unit/auto_link_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/unit/auto_link_spec.rb b/spec/unit/auto_link_spec.rb index 7f7168a0153..e50153152dd 100644 --- a/spec/unit/auto_link_spec.rb +++ b/spec/unit/auto_link_spec.rb @@ -40,6 +40,13 @@ match(%r{Hello World}) end + it "should keep locale in the url if present" do + expect(self).to receive(:url_options).and_return(locale: 'en') + + expect(auto_link(post)).to \ + match(%r{Hello World}) + end + context "but the user doesn't have access" do before do allow(self).to receive(:authorized?).and_return(false) @@ -62,6 +69,13 @@ expect(auto_link(post)).to \ match(%r{Hello World}) end + + it "should keep locale in the url if present" do + expect(self).to receive(:url_options).and_return(locale: 'en') + + expect(auto_link(post)).to \ + match(%r{Hello World}) + end end context "when the resource is registered with the show & edit actions disabled" do From f40d8e0e32de8c504d4adf4335cdbda44a81d9b7 Mon Sep 17 00:00:00 2001 From: Timo Schilling Date: Wed, 22 Feb 2017 07:22:44 +0100 Subject: [PATCH 0372/3836] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ccea00e7119..fa345c9dca4 100644 --- a/README.md +++ b/README.md @@ -47,12 +47,11 @@ gem 'activeadmin', git: 'https://github.com/activeadmin/activeadmin', branch: '0 ## Documentation -Please note that is out of date. For the latest docs, check out the -Github [docs](https://github.com/activeadmin/activeadmin/tree/master/docs#activeadmin-documentation) and the [wiki](https://github.com/activeadmin/activeadmin/wiki). +For the latest docs, check out the Github and the [wiki](https://github.com/activeadmin/activeadmin/wiki). ## Links -* Website: (out of date) +* Website: * Live demo: * Documentation * Guides: @@ -67,7 +66,7 @@ Github [docs](https://github.com/activeadmin/activeadmin/tree/master/docs#active ## Getting started -Check out [the docs](https://github.com/activeadmin/activeadmin/blob/master/docs/0-installation.md)! +Check out [the docs](http://activeadmin.info/0-installation.html)! ## Need help? @@ -78,8 +77,7 @@ Ask us in IRC ([#activeadmin](https://webchat.freenode.net/?channels=activeadmin ## Want to contribute? The [contributing guide](https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md) -is a good place to start. If you have questions, feel free to ask -[@seanlinsley](https://twitter.com/seanlinsley) or [@captainhagbard](https://twitter.com/captainhagbard). +is a good place to start. If you have questions, feel free to ask. ## Dependencies From fd9d13145102e196fc4b67e5667e914364dc0967 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Mon, 30 Jan 2017 23:38:01 +0200 Subject: [PATCH 0373/3836] Revert "Merge pull request #4618 from geome/3280-added-nested-belongs-to-rebased" This reverts commit a8b3bef3a678919a69f808e7516219294a03f553, reversing changes made to 9fb572a4f10353508e7f6876594a9989cf550367. --- features/belongs_to.feature | 18 ---------- features/support/paths.rb | 3 -- lib/active_admin/base_controller/menu.rb | 2 +- lib/active_admin/page.rb | 9 +++-- lib/active_admin/resource.rb | 15 ++++---- lib/active_admin/resource/routes.rb | 26 +++++++------- lib/active_admin/resource_dsl.rb | 4 +-- lib/active_admin/router.rb | 23 ++++++------ .../view_helpers/breadcrumb_helper.rb | 7 ++-- spec/support/rails_template.rb | 6 ---- spec/unit/belongs_to_spec.rb | 6 ++-- spec/unit/page_spec.rb | 2 +- spec/unit/resource/routes_spec.rb | 35 +------------------ spec/unit/resource_spec.rb | 4 +-- spec/unit/routing_spec.rb | 25 ------------- spec/unit/view_helpers/breadcrumbs_spec.rb | 4 +-- 16 files changed, 50 insertions(+), 139 deletions(-) diff --git a/features/belongs_to.feature b/features/belongs_to.feature index 13b73e7364a..f7c8f1b6a07 100644 --- a/features/belongs_to.feature +++ b/features/belongs_to.feature @@ -110,24 +110,6 @@ Feature: Belongs To When I follow "Posts" Then the "Posts" tab should be selected - Scenario: When the belongs to is nested - Given a configuration of: - """ - ActiveAdmin.register User - ActiveAdmin.register Post do - belongs_to :user - end - ActiveAdmin.register Tagging do - belongs_to :user - belongs_to :post - end - """ - When I go to the last author's last post's taggings - Then I should see a link to "Users" in the breadcrumb - And I should see a link to "Jane Doe" in the breadcrumb - And I should see a link to "Posts" in the breadcrumb - And I should see a link to "Hello World" in the breadcrumb - Scenario: Displaying belongs to resources in main menu Given a configuration of: """ diff --git a/features/support/paths.rb b/features/support/paths.rb index aac94b43060..21287f15547 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -50,9 +50,6 @@ def path_to(page_name) when /^the last post's show page$/ admin_post_path(Post.last) - when /^the last author's last post's taggings$/ - admin_user_post_taggings_path(User.last, Post.where(author_id: User.last.id).last) - when /^the last post's edit page$/ edit_admin_post_path(Post.last) diff --git a/lib/active_admin/base_controller/menu.rb b/lib/active_admin/base_controller/menu.rb index 7303f0b21da..07c3d37b208 100644 --- a/lib/active_admin/base_controller/menu.rb +++ b/lib/active_admin/base_controller/menu.rb @@ -22,7 +22,7 @@ def current_menu # Get's called through a before filter def set_current_tab @current_tab = if current_menu && active_admin_config.belongs_to? && parent? - parent_item = active_admin_config.belongs_to_config.first.target.menu_item + parent_item = active_admin_config.belongs_to_config.target.menu_item if current_menu.include? parent_item parent_item else diff --git a/lib/active_admin/page.rb b/lib/active_admin/page.rb index e448e180221..fba967c425b 100644 --- a/lib/active_admin/page.rb +++ b/lib/active_admin/page.rb @@ -85,19 +85,18 @@ def clear_page_actions! end def belongs_to(target, options = {}) - this_belongs_to = Resource::BelongsTo.new(self, target, options) - belongs_to_config << this_belongs_to - self.navigation_menu_name = target unless this_belongs_to.optional? + @belongs_to = Resource::BelongsTo.new(self, target, options) + self.navigation_menu_name = target unless @belongs_to.optional? controller.send :belongs_to, target, options.dup end def belongs_to_config - @belongs_to ||= [] + @belongs_to end # Do we belong to another resource? def belongs_to? - belongs_to_config.length > 0 + !!belongs_to_config end def breadcrumb diff --git a/lib/active_admin/resource.rb b/lib/active_admin/resource.rb index a532c87ff2c..03ee4010257 100644 --- a/lib/active_admin/resource.rb +++ b/lib/active_admin/resource.rb @@ -125,23 +125,24 @@ def defined_actions end def belongs_to(target, options = {}) - this_belongs_to = Resource::BelongsTo.new(self, target, options) - self.navigation_menu_name = target unless this_belongs_to.optional? - belongs_to_config << this_belongs_to + @belongs_to = Resource::BelongsTo.new(self, target, options) + self.navigation_menu_name = target unless @belongs_to.optional? controller.send :belongs_to, target, options.dup end def belongs_to_config - @belongs_to ||= [] + @belongs_to end - def belongs_to_params - belongs_to_config.select{ |c| c.required? }.map{ |c| c.to_param } + def belongs_to_param + if belongs_to? && belongs_to_config.required? + belongs_to_config.to_param + end end # Do we belong to another resource? def belongs_to? - belongs_to_config.length > 0 + !!belongs_to_config end # The csv builder for this resource diff --git a/lib/active_admin/resource/routes.rb b/lib/active_admin/resource/routes.rb index 2bca05617c3..ce30d3199c1 100644 --- a/lib/active_admin/resource/routes.rb +++ b/lib/active_admin/resource/routes.rb @@ -92,7 +92,7 @@ def route_name(resource_path_name, options = {}) route << options[:action] # "batch_action", "edit" or "new" route << resource.route_prefix # "admin" - route += belongs_to_names + route << belongs_to_name if nested? # "category" route << resource_path_name # "posts" or "post" route << suffix # "path" or "index path" @@ -102,25 +102,25 @@ def route_name(resource_path_name, options = {}) # @return params to pass to instance path def route_instance_params(instance) - belongs_to_names.reverse.reduce([instance]) do |arr,name| - arr + [arr.last.public_send(name)] - end.map{|i| i.to_param }.reverse + if nested? + [instance.public_send(belongs_to_name).to_param, instance.to_param] + else + instance.to_param + end end def route_collection_params(params) - belongs_to_names.map{|name| params[:"#{name}_id"]} + if nested? + params[:"#{belongs_to_name}_id"] + end end - def belongs_to_names - required_belongs_to.map{|bc| bc.target.resource_name.singular } + def nested? + resource.belongs_to? && resource.belongs_to_config.required? end - def required_belongs_to - if resource.belongs_to? - resource.belongs_to_config.select{|bc| bc.required?} - else - [] - end + def belongs_to_name + resource.belongs_to_config.target.resource_name.singular if nested? end def routes diff --git a/lib/active_admin/resource_dsl.rb b/lib/active_admin/resource_dsl.rb index c730d6b8f93..e9cb2cb0c19 100644 --- a/lib/active_admin/resource_dsl.rb +++ b/lib/active_admin/resource_dsl.rb @@ -68,11 +68,11 @@ def includes(*args) # def permit_params(*args, &block) param_key = config.param_key.to_sym - belongs_to_params = config.belongs_to_params + belongs_to_param = config.belongs_to_param controller do define_method :permitted_params do - params.permit *(active_admin_namespace.permitted_params + belongs_to_params), + params.permit *(active_admin_namespace.permitted_params + Array.wrap(belongs_to_param)), param_key => block ? instance_exec(&block) : args end end diff --git a/lib/active_admin/router.rb b/lib/active_admin/router.rb index f850db5042b..042bbecde00 100644 --- a/lib/active_admin/router.rb +++ b/lib/active_admin/router.rb @@ -38,22 +38,19 @@ def define_resource_routes(router) resources.each do |config| routes = aa_router.resource_routes(config) - # Add in the parents for each, starting from the first(out) to the last(in) exists - - if(config.belongs_to?) - belongs_to = config.belongs_to_config.reverse.reduce(routes) do |r,btc| - Proc.new do - # If it's optional, make the normal resource routes - instance_exec &r if btc.optional? + # Add in the parent if it exists + if config.belongs_to? + belongs_to = routes + routes = Proc.new do + # If it's optional, make the normal resource routes + instance_exec &belongs_to if config.belongs_to_config.optional? - # Make the nested belongs_to routes - # :only is set to nothing so that we don't clobber any existing routes on the resource - resources btc.target.resource_name.plural, only: [] do - instance_exec &r - end + # Make the nested belongs_to routes + # :only is set to nothing so that we don't clobber any existing routes on the resource + resources config.belongs_to_config.target.resource_name.plural, only: [] do + instance_exec &belongs_to end end - routes = belongs_to end # Add on the namespace if required diff --git a/lib/active_admin/view_helpers/breadcrumb_helper.rb b/lib/active_admin/view_helpers/breadcrumb_helper.rb index e560b899e32..3d3e01fd5a4 100644 --- a/lib/active_admin/view_helpers/breadcrumb_helper.rb +++ b/lib/active_admin/view_helpers/breadcrumb_helper.rb @@ -13,10 +13,9 @@ def breadcrumb_links(path = request.path) # 2. try using the model name translation # 3. default to calling `titlecase` on the URL fragment if part =~ /\A(\d+|[a-f0-9]{24})\z/ && parts[index-1] - config = active_admin_config.belongs_to_config.map(&:target).select do |parent| - parent.resource_name.route_key == parts[index-1] - end.first || active_admin_config - name = display_name config.find_resource part + parent = active_admin_config.belongs_to_config.try :target + config = parent && parent.resource_name.route_key == parts[index-1] ? parent : active_admin_config + name = display_name config.find_resource part end name ||= I18n.t "activerecord.models.#{part.singularize}", count: ::ActiveAdmin::Helpers::I18n::PLURAL_MANY_COUNT, default: part.titlecase diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index b4fba8d644e..99712077fcc 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -33,12 +33,6 @@ class Post < ActiveRecord::Base RUBY copy_file File.expand_path('../templates/post_decorator.rb', __FILE__), 'app/models/post_decorator.rb' -generate :model, "post_comment message:string post_id:integer" -inject_into_file 'app/models/post_comment.rb', %q{ - belongs_to :post - attr_accessible :message, :post unless Rails::VERSION::MAJOR > 3 && !defined? ProtectedAttributes - }, after: 'class PostComment < ActiveRecord::Base' - generate :model, 'blog/post title:string body:text published_date:date author_id:integer ' + 'position:integer custom_category_id:integer starred:boolean foo_id:integer' create_file 'app/models/blog/post.rb', <<-RUBY.strip_heredoc, force: true diff --git a/spec/unit/belongs_to_spec.rb b/spec/unit/belongs_to_spec.rb index 749d3462b69..d3ab3c31d38 100644 --- a/spec/unit/belongs_to_spec.rb +++ b/spec/unit/belongs_to_spec.rb @@ -9,10 +9,10 @@ end let(:namespace) { ActiveAdmin.application.namespace(:admin) } + let(:user_config){ ActiveAdmin.register User } + let(:post_config){ ActiveAdmin.register Post do belongs_to :user end } + let(:belongs_to){ post_config.belongs_to_config } - let(:user_config){ namespace.resource_for('User') } - let(:post_config){ namespace.resource_for('Post') } - let(:belongs_to){ post_config.belongs_to_config.first } it "should have an owner" do expect(belongs_to.owner).to eq post_config diff --git a/spec/unit/page_spec.rb b/spec/unit/page_spec.rb index 9405db94887..ed72594b63f 100644 --- a/spec/unit/page_spec.rb +++ b/spec/unit/page_spec.rb @@ -97,7 +97,7 @@ def config(options = {}) end it "builds a belongs_to relationship" do - belongs_to = page_config.belongs_to_config.first + belongs_to = page_config.belongs_to_config expect(belongs_to.target).to eq(post_config) expect(belongs_to.owner).to eq(page_config) diff --git a/spec/unit/resource/routes_spec.rb b/spec/unit/resource/routes_spec.rb index 8881ace3891..ac337274b55 100644 --- a/spec/unit/resource/routes_spec.rb +++ b/spec/unit/resource/routes_spec.rb @@ -85,39 +85,6 @@ class ::News; def self.has_many(*); end end end end - context "when the resources belongs to two other resources" do - let(:config) { namespace.resource_for('Tagging') } - - let :tagging do - Tagging.new do |t| - t.id = 4 - t.post = Post.new do |p| - p.id = 3 - p.category = Category.new{ |c| c.id = 1 } - end - end - end - - before do - load_resources do - ActiveAdmin.register Category - ActiveAdmin.register Post - ActiveAdmin.register Tagging do - belongs_to :category - belongs_to :post - end - end - end - - it "should nest the collection path" do - expect(config.route_collection_path(category_id: 1, post_id: 3)).to eq "/admin/categories/1/posts/3/taggings" - end - - it "should nest the instance path" do - expect(config.route_instance_path(tagging)).to eq "/admin/categories/1/posts/3/taggings/4" - end - end - context "for batch_action handler" do before do load_resources { config.batch_actions = true } @@ -154,4 +121,4 @@ class ::News; def self.has_many(*); end end end end end -end +end \ No newline at end of file diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index f189a056595..0f622244ed3 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -80,9 +80,9 @@ def config(options = {}) describe "#belongs_to" do it "should build a belongs to configuration" do - expect(config.belongs_to_config.length).to eq 0 + expect(config.belongs_to_config).to eq nil config.belongs_to :posts - expect(config.belongs_to_config.length).to eq 1 + expect(config.belongs_to_config).to_not eq nil end it "should set the target menu to the belongs to target" do diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index 6343274765b..8eeb441975d 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -175,31 +175,6 @@ end end - describe "nested belongs to resource" do - before do - ActiveAdmin.register(Tagging) do - belongs_to :user, optional: true - belongs_to :post - end - reload_routes! - end - it "should route the nested index path" do - expect(admin_user_post_taggings_path(1,2)).to eq "/admin/users/1/posts/2/taggings" - end - - it "should route the nested show path" do - expect(admin_user_post_tagging_path(1,2,3)).to eq "/admin/users/1/posts/2/taggings/3" - end - - it "should route the nested skipping optional index path" do - expect(admin_post_taggings_path(1)).to eq "/admin/posts/1/taggings" - end - - it "should route the nested skipping optional show path" do - expect(admin_post_tagging_path(1,2)).to eq "/admin/posts/1/taggings/2" - end - end - describe "page" do context "when default namespace" do before(:each) do diff --git a/spec/unit/view_helpers/breadcrumbs_spec.rb b/spec/unit/view_helpers/breadcrumbs_spec.rb index 21a1c4876c3..458a3a340df 100644 --- a/spec/unit/view_helpers/breadcrumbs_spec.rb +++ b/spec/unit/view_helpers/breadcrumbs_spec.rb @@ -16,7 +16,7 @@ def link_to(name, url); {name: name, path: url}; end defined_actions: actions } let(:post) { double display_name: 'Hello World' } let(:post_config) { double find_resource: post, resource_name: double(route_key: 'posts'), - defined_actions: actions, belongs_to_config: [double(target: user_config)] } + defined_actions: actions, belongs_to_config: double(target: user_config) } let :active_admin_config do post_config @@ -193,7 +193,7 @@ def link_to(name, url); {name: name, path: url}; end context "when the 'show' action is disabled" do let(:post_config) { double find_resource: post, resource_name: double(route_key: 'posts'), defined_actions: actions - [:show], # this is the change - belongs_to_config: [double(target: user_config)] } + belongs_to_config: double(target: user_config) } let(:path) { "/admin/posts/1/edit" } From 50d0e0f35f0a7bef727de161dc62369043233b95 Mon Sep 17 00:00:00 2001 From: Ryan Hertz Date: Wed, 22 Feb 2017 08:38:41 -0500 Subject: [PATCH 0374/3836] closed code block in docs --- docs/2-resource-customization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index 29b643e44f9..a7f22f03321 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -72,7 +72,7 @@ ActiveAdmin.register Post do belongs_to :user permit_params :title, :content, :publisher_id end - +``` The `permit_params` call creates a method called `permitted_params`. You should use this method when overriding `create` or `update` actions: From 88d25537c90a35f650c40ff174f384d91823a749 Mon Sep 17 00:00:00 2001 From: Ryan Hertz Date: Wed, 22 Feb 2017 08:57:14 -0500 Subject: [PATCH 0375/3836] added csv_filename override to csv docs --- docs/4-csv-format.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/4-csv-format.md b/docs/4-csv-format.md index 6b3a69ed26c..bba3f8635ba 100644 --- a/docs/4-csv-format.md +++ b/docs/4-csv-format.md @@ -39,6 +39,18 @@ config.csv_options = { col_sep: ';' } config.csv_options = { force_quotes: true } ``` +You can customize the filename by overriding `csv_filename` in the controller block. +```ruby +ActiveAdmin.register User do + controller do + def csv_filename + 'User Details.csv' + end + end +end +``` + + ## Streaming By default Active Admin streams the CSV response to your browser as it's generated. From c68bf3f398d41f5a037aa9c2c8d82ea004102de7 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Thu, 23 Feb 2017 11:35:34 -0500 Subject: [PATCH 0376/3836] GitHub pages Gemfile. --- docs/Gemfile | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 docs/Gemfile diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 00000000000..4a0b1697d89 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,2 @@ +gem 'github-pages' +gem 'jekyll-redirect-from' From a03804df8ca59759b7c014e44e174a0c9f007ae7 Mon Sep 17 00:00:00 2001 From: Piers Chambers Date: Thu, 23 Feb 2017 11:27:32 -0500 Subject: [PATCH 0377/3836] Add redirects from docs --- docs/0-installation.md | 3 +++ docs/1-general-configuration.md | 3 +++ docs/10-custom-pages.md | 3 +++ docs/11-decorators.md | 3 +++ docs/12-arbre-components.md | 3 +++ docs/13-authorization-adapter.md | 3 +++ docs/14-gotchas.md | 3 +++ docs/2-resource-customization.md | 3 +++ docs/3-index-pages.md | 3 +++ docs/3-index-pages/custom-index.md | 3 +++ docs/3-index-pages/index-as-block.md | 3 +++ docs/3-index-pages/index-as-blog.md | 3 +++ docs/3-index-pages/index-as-grid.md | 3 +++ docs/3-index-pages/index-as-table.md | 3 +++ docs/4-csv-format.md | 3 +++ docs/5-forms.md | 3 +++ docs/6-show-pages.md | 3 +++ docs/7-sidebars.md | 3 +++ docs/8-custom-actions.md | 3 +++ docs/9-batch-actions.md | 3 +++ docs/_config.yml | 2 ++ docs/documentation.md | 2 +- 22 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 docs/_config.yml diff --git a/docs/0-installation.md b/docs/0-installation.md index dd951fb9d12..e3b7181608c 100644 --- a/docs/0-installation.md +++ b/docs/0-installation.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/0-installation.html +--- # Installation Active Admin is a Ruby Gem. diff --git a/docs/1-general-configuration.md b/docs/1-general-configuration.md index 18de6d147b8..e512eed3f9b 100644 --- a/docs/1-general-configuration.md +++ b/docs/1-general-configuration.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/1-general-configuration.html +--- # General Configuration You can configure Active Admin settings in `config/initializers/active_admin.rb`. diff --git a/docs/10-custom-pages.md b/docs/10-custom-pages.md index 108c59758b3..fd9caa10fe1 100644 --- a/docs/10-custom-pages.md +++ b/docs/10-custom-pages.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/10-custom-pages.html +--- # Custom Pages If you have data you want on a standalone page that isn't tied to a resource, diff --git a/docs/11-decorators.md b/docs/11-decorators.md index fc11bbe05b2..64ec437166e 100644 --- a/docs/11-decorators.md +++ b/docs/11-decorators.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/11-decorators.html +--- # Decorators Active Admin allows you to use the decorator pattern to provide view-specific diff --git a/docs/12-arbre-components.md b/docs/12-arbre-components.md index e32021ef618..0e823347ff2 100644 --- a/docs/12-arbre-components.md +++ b/docs/12-arbre-components.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/12-arbre-components.html +--- # Arbre Components Arbre allows the creation of shareable and extendable HTML components and is diff --git a/docs/13-authorization-adapter.md b/docs/13-authorization-adapter.md index 33346ee6110..0ea34ad87f1 100644 --- a/docs/13-authorization-adapter.md +++ b/docs/13-authorization-adapter.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/13-authorization-adapter.html +--- # Authorization Adapter Active Admin offers the ability to define and use your own authorization diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 15972f30146..dfc4e340082 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/14-gotchas.html +--- #Gotchas ## Security diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index a7f22f03321..a5324b8c979 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/2-resource-customization.html +--- # Working with Resources Every Active Admin resource corresponds to a Rails model. So before creating a diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index 6635dcadb22..9e4d79795e2 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/3-index-pages.html +--- # Customizing the Index Page Filtering and listing resources is one of the most important tasks for diff --git a/docs/3-index-pages/custom-index.md b/docs/3-index-pages/custom-index.md index d868701f6f5..e9ec8c3af9b 100644 --- a/docs/3-index-pages/custom-index.md +++ b/docs/3-index-pages/custom-index.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/3-index-pages/custom-index.html +--- # Custom Index If the supplied Active Admin index components are insufficient for your project diff --git a/docs/3-index-pages/index-as-block.md b/docs/3-index-pages/index-as-block.md index b74de5f162e..aaf4010bc36 100644 --- a/docs/3-index-pages/index-as-block.md +++ b/docs/3-index-pages/index-as-block.md @@ -1,3 +1,6 @@ +--- +redirect_from: /docs/3-index-pages/index-as-block.html +--- + +### Expected behavior + + + +### Actual behavior + + + +### How to reproduce + + From a1afdad76740a453cf15ecf1656933937670b66e Mon Sep 17 00:00:00 2001 From: Fred Ngo Date: Mon, 22 May 2017 17:03:24 -0400 Subject: [PATCH 0532/3836] Update en-GB translations, add en-CA translations. --- config/locales/en-CA.yml | 138 +++++++++++++++++++++++++++++++++++++++ config/locales/en-GB.yml | 44 ++++++++++++- 2 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 config/locales/en-CA.yml diff --git a/config/locales/en-CA.yml b/config/locales/en-CA.yml new file mode 100644 index 00000000000..d4027c18be2 --- /dev/null +++ b/config/locales/en-CA.yml @@ -0,0 +1,138 @@ +"en-CA": + active_admin: + dashboard: Dashboard + dashboard_welcome: + welcome: "Welcome to Active Admin. This is the default dashboard page." + call_to_action: "To add dashboard sections, checkout 'app/admin/dashboards.rb'" + view: "View" + edit: "Edit" + delete: "Delete" + delete_confirmation: "Are you sure you want to delete this?" + create_another: "Create another %{model}" + new_model: "New %{model}" + edit_model: "Edit %{model}" + delete_model: "Delete %{model}" + details: "%{model} Details" + cancel: "Cancel" + empty: "Empty" + previous: "Previous" + next: "Next" + download: "Download:" + has_many_new: "Add New %{model}" + has_many_delete: "Delete" + has_many_remove: "Remove" + filters: + buttons: + filter: "Filter" + clear: "Clear Filters" + predicates: + contains: "Contains" + equals: "Equals" + starts_with: "Starts with" + ends_with: "Ends with" + greater_than: "Greater than" + less_than: "Less than" + search_status: + headline: "Search status:" + current_scope: "Scope:" + current_filters: "Current filters:" + no_current_filters: "None" + status_tag: + "yes": "Yes" + "no": "No" + main_content: "Please implement %{model}#main_content to display content." + logout: "Logout" + powered_by: "Powered by %{active_admin} %{version}" + sidebars: + filters: "Filters" + search_status: "Search Status" + pagination: + empty: "No %{model} found" + one: "Displaying 1 %{model}" + one_page: "Displaying all %{n} %{model}" + multiple: "Displaying %{model} %{from} - %{to} of %{total} in total" + multiple_without_total: "Displaying %{model} %{from} - %{to}" + per_page: "Per page: " + entry: + one: "entry" + other: "entries" + any: "Any" + blank_slate: + content: "There are no %{resource_name} yet." + link: "Create one" + dropdown_actions: + button_label: "Actions" + batch_actions: + button_label: "Batch Actions" + default_confirmation: "Are you sure you want to do this?" + delete_confirmation: "Are you sure you want to delete these %{plural_model}?" + succesfully_destroyed: + one: "Successfully destroyed 1 %{model}" + other: "Successfully destroyed %{count} %{plural_model}" + selection_toggle_explanation: "(Toggle Selection)" + action_label: "%{title} Selected" + labels: + destroy: "Delete" + comments: + created_at: "Created" + resource_type: "Resource Type" + author_type: "Author Type" + body: "Body" + author: "Author" + add: "Add Comment" + delete: "Delete Comment" + delete_confirmation: "Are you sure you want to delete these comment?" + resource: "Resource" + no_comments_yet: "No comments yet." + author_missing: "Anonymous" + title_content: "Comments (%{count})" + errors: + empty_text: "Comment wasn't saved, text was empty." + devise: + username: + title: "Username" + email: + title: "Email" + subdomain: + title: "Subdomain" + password: + title: "Password" + password_confirmation: + title: "Confirm Password" + sign_up: + title: "Sign up" + submit: "Sign up" + login: + title: "Login" + remember_me: "Remember me" + submit: "Login" + reset_password: + title: "Forgot your password?" + submit: "Reset My Password" + change_password: + title: "Change your password" + submit: "Change my password" + unlock: + title: "Resend unlock instructions" + submit: "Resend unlock instructions" + resend_confirmation_instructions: + title: "Resend confirmation instructions" + submit: "Resend confirmation instructions" + links: + sign_up: "Sign up" + sign_in: "Sign in" + forgot_your_password: "Forgot your password?" + sign_in_with_omniauth_provider: "Sign in with %{provider}" + resend_unlock_instructions: "Resend unlock instructions" + resend_confirmation_instructions: "Resend confirmation instructions" + unsupported_browser: + headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." + recommendation: "We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox." + turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." + access_denied: + message: "You are not authorized to perform this action." + index_list: + table: "Table" + block: "List" + grid: "Grid" + blog: "Blog" diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 68a674d99ee..da63bae56f0 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -8,6 +8,7 @@ edit: "Edit" delete: "Delete" delete_confirmation: "Are you sure you want to delete this?" + create_another: "Create another %{model}" new_model: "New %{model}" edit_model: "Edit %{model}" delete_model: "Delete %{model}" @@ -31,6 +32,11 @@ ends_with: "Ends with" greater_than: "Greater than" less_than: "Less than" + search_status: + headline: "Search status:" + current_scope: "Scope:" + current_filters: "Current filters:" + no_current_filters: "None" status_tag: "yes": "Yes" "no": "No" @@ -39,12 +45,14 @@ powered_by: "Powered by %{active_admin} %{version}" sidebars: filters: "Filters" + search_status: "Search Status" pagination: empty: "No %{model} found" one: "Displaying 1 %{model}" one_page: "Displaying all %{n} %{model}" multiple: "Displaying %{model} %{from} - %{to} of %{total} in total" multiple_without_total: "Displaying %{model} %{from} - %{to}" + per_page: "Per page: " entry: one: "entry" other: "entries" @@ -66,9 +74,14 @@ labels: destroy: "Delete" comments: + created_at: "Created" + resource_type: "Resource Type" + author_type: "Author Type" body: "Body" author: "Author" add: "Add Comment" + delete: "Delete Comment" + delete_confirmation: "Are you sure you want to delete these comment?" resource: "Resource" no_comments_yet: "No comments yet." author_missing: "Anonymous" @@ -76,6 +89,19 @@ errors: empty_text: "Comment wasn't saved, text was empty." devise: + username: + title: "Username" + email: + title: "Email" + subdomain: + title: "Subdomain" + password: + title: "Password" + password_confirmation: + title: "Confirm Password" + sign_up: + title: "Sign up" + submit: "Sign up" login: title: "Login" remember_me: "Remember me" @@ -86,11 +112,27 @@ change_password: title: "Change your password" submit: "Change my password" + unlock: + title: "Resend unlock instructions" + submit: "Resend unlock instructions" resend_confirmation_instructions: title: "Resend confirmation instructions" submit: "Resend confirmation instructions" links: + sign_up: "Sign up" sign_in: "Sign in" forgot_your_password: "Forgot your password?" sign_in_with_omniauth_provider: "Sign in with %{provider}" - resend_unlock_instructions: "Re-send unlock instructions" + resend_unlock_instructions: "Resend unlock instructions" + resend_confirmation_instructions: "Resend confirmation instructions" + unsupported_browser: + headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." + recommendation: "We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox." + turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." + access_denied: + message: "You are not authorised to perform this action." + index_list: + table: "Table" + block: "List" + grid: "Grid" + blog: "Blog" From 934e3c22ab2bb3ca310ad312ee0bc134265431c8 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Mon, 1 May 2017 19:54:18 +0300 Subject: [PATCH 0533/3836] rework displaying current scope in active filters section --- features/index/index_scopes.feature | 8 ++++++++ features/step_definitions/index_scope_steps.rb | 4 ++++ lib/active_admin/filters/active.rb | 7 +------ lib/active_admin/filters/resource_extension.rb | 7 +++++-- .../resource_controller/data_access.rb | 2 ++ lib/active_admin/view_helpers.rb | 1 + .../view_helpers/scope_name_helper.rb | 16 ++++++++++++++++ lib/active_admin/views/components/scopes.rb | 13 +++---------- 8 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 lib/active_admin/view_helpers/scope_name_helper.rb diff --git a/features/index/index_scopes.feature b/features/index/index_scopes.feature index 550a66c0ad2..6f494aba951 100644 --- a/features/index/index_scopes.feature +++ b/features/index/index_scopes.feature @@ -32,6 +32,9 @@ Feature: Index Scoping """ Then I should see the scope with label "Neat scope" And I should see 3 posts in the table + When I follow "Neat scope" + And I should see 3 posts in the table + And I should see the current scope with label "Neat scope" Scenario: Viewing resources with one scope as the default Given 3 posts exist @@ -70,6 +73,7 @@ Feature: Index Scoping And I press "Filter" Then I should see the scope "All" selected + Scenario: Viewing resources with a scope but scope_count turned off Given 3 posts exist And an index configuration of: @@ -113,6 +117,7 @@ Feature: Index Scoping And I should see the scope "Published" with the count 3 When I follow "Published" Then I should see the scope "Published" selected + Then I should see the current scope with label "Published" And I should see 3 posts in the table Scenario: Viewing resources when scoping and filtering @@ -137,6 +142,7 @@ Feature: Index Scoping When I follow "Published" Then I should see the scope "Published" selected + And I should see the current scope with label "Published" And I should see the scope "All" with the count 6 And I should see the scope "Published" with the count 3 And I should see 3 posts in the table @@ -196,6 +202,7 @@ Feature: Index Scoping Then I should see the scope "Tomorrow" selected And I should see the scope "Today" not selected And I should see a link to "Today" + And I should see the current scope with label "Tomorrow" Scenario: Viewing resources with scopes when scoping to user Given 2 posts written by "Daft Punk" exist @@ -268,3 +275,4 @@ Feature: Index Scoping And I should see the scope "All" with the count 1 And I should see the scope "Published" with the count 1 And I should see 1 posts in the table + And I should see the current scope with label "Published" diff --git a/features/step_definitions/index_scope_steps.rb b/features/step_definitions/index_scope_steps.rb index fe7b585f903..4635617e4e4 100644 --- a/features/step_definitions/index_scope_steps.rb +++ b/features/step_definitions/index_scope_steps.rb @@ -18,6 +18,10 @@ expect(page).to have_link(label) end +Then /^I should see the current scope with label "([^"]*)"$/ do |label| + expect(page).to have_css '.current_scope_name', text: label +end + Then /^I should see the scope "([^"]*)" with no count$/ do |name| name = name.tr(" ", "").underscore.downcase expect(page).to have_css ".scopes .#{name}" diff --git a/lib/active_admin/filters/active.rb b/lib/active_admin/filters/active.rb index 8667fbe7b95..dfb41c31fa4 100644 --- a/lib/active_admin/filters/active.rb +++ b/lib/active_admin/filters/active.rb @@ -4,12 +4,11 @@ module ActiveAdmin module Filters class Active - attr_accessor :filters, :scope + attr_accessor :filters def initialize(resource_class, params) @resource_class = resource_class @params = params.to_unsafe_h - @scope = humanize_scope @filters = build_filters end @@ -20,10 +19,6 @@ def build_filters filters.map{ |param| Humanized.new(param) } end - def humanize_scope - scope = @params['scope'] - scope ? scope.humanize : "All" - end end end diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index 2505f3c713a..118e10ef4db 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -156,8 +156,11 @@ def search_status_section active = ActiveAdmin::Filters::Active.new(resource_class, params) span do - h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline' - b active.scope, style: "display: inline" + + if active_admin_config.scopes.any? + h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline' + b scope_name(current_scope), class: 'current_scope_name', style: "display: inline" + end div style: "margin-top: 10px" do h4 I18n.t("active_admin.search_status.current_filters"), style: 'margin-bottom: 10px' diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index d3c140ba6f9..0b8c2ad69ef 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -14,6 +14,8 @@ def self.included(base) include ScopeChain define_active_admin_callbacks :build, :create, :update, :save, :destroy + + helper_method :current_scope end end diff --git a/lib/active_admin/view_helpers.rb b/lib/active_admin/view_helpers.rb index 8ffc484d79d..7402a83122b 100644 --- a/lib/active_admin/view_helpers.rb +++ b/lib/active_admin/view_helpers.rb @@ -14,6 +14,7 @@ module ViewHelpers include TitleHelper include ViewFactoryHelper include FlashHelper + include ScopeNameHelper end end diff --git a/lib/active_admin/view_helpers/scope_name_helper.rb b/lib/active_admin/view_helpers/scope_name_helper.rb new file mode 100644 index 00000000000..70dd787f3eb --- /dev/null +++ b/lib/active_admin/view_helpers/scope_name_helper.rb @@ -0,0 +1,16 @@ +module ActiveAdmin + module ViewHelpers + module ScopeNameHelper + + def scope_name(scope) + case scope.name + when Proc then + self.instance_exec(&scope.name).to_s + else + scope.name.to_s + end + end + + end + end +end \ No newline at end of file diff --git a/lib/active_admin/views/components/scopes.rb b/lib/active_admin/views/components/scopes.rb index 9864a5c3427..8c967f24139 100644 --- a/lib/active_admin/views/components/scopes.rb +++ b/lib/active_admin/views/components/scopes.rb @@ -30,11 +30,10 @@ def build(scopes, options = {}) def build_scope(scope, options) li class: classes_for_scope(scope) do - scope_name = I18n.t "active_admin.scopes.#{scope.id}", default: name_for_scope(scope) - params = request.query_parameters.except :page, :scope, :commit, :format + params = request.query_parameters.except :page, :scope, :commit, :format a href: url_for(scope: scope.id, params: params), class: 'table_tools_button' do - text_node scope_name + text_node scope_name(scope) span class: 'count' do "(#{get_scope_count(scope)})" end if options[:scope_count] && scope.show_count @@ -61,12 +60,6 @@ def get_scope_count(scope) collection_size(scope_chain(scope, collection_before_scope)) end - def name_for_scope(scope) - case scope.name - when Proc then self.instance_exec(&scope.name).to_s - else scope.name.to_s - end - end end end -end +end \ No newline at end of file From 178f09b47742dfe0645cc38f90168bd3481035c9 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 10 May 2017 01:49:41 +0300 Subject: [PATCH 0534/3836] rework displaying current filters in active filters section --- features/index/filters.feature | 4 + features/step_definitions/filter_steps.rb | 5 ++ lib/active_admin/filters/active.rb | 20 +++-- lib/active_admin/filters/active_filter.rb | 75 ++++++++++++++++ lib/active_admin/filters/humanized.rb | 68 -------------- .../filters/resource_extension.rb | 15 ++-- spec/unit/filters/active_filter_spec.rb | 90 +++++++++++++++++++ spec/unit/filters/active_spec.rb | 12 ++- spec/unit/filters/humanized_spec.rb | 64 ------------- 9 files changed, 205 insertions(+), 148 deletions(-) create mode 100644 lib/active_admin/filters/active_filter.rb delete mode 100644 lib/active_admin/filters/humanized.rb create mode 100644 spec/unit/filters/active_filter_spec.rb delete mode 100644 spec/unit/filters/humanized_spec.rb diff --git a/features/index/filters.feature b/features/index/filters.feature index a39c6bc650b..77789394a7c 100644 --- a/features/index/filters.feature +++ b/features/index/filters.feature @@ -21,6 +21,7 @@ Feature: Index Filtering And I press "Filter" And I should see 1 posts in the table And I should see "Hello World 2" within ".index_table" + And I should see current filter "title_contains" equal to "Hello World 2" with label "Title contains" Scenario: Filtering posts with no results Given 3 posts exist @@ -100,6 +101,7 @@ Feature: Index Filtering Then I should see 1 posts in the table And I should see "Hello World" within ".index_table" And the "Jane Doe" checkbox should be checked + And I should see current filter "author_id_in" equal to "Jane Doe" Scenario: Disabling filters Given an index configuration of: @@ -122,6 +124,7 @@ Feature: Index Filtering Then I should see 1 categories in the table And I should see "Non-Fiction" within ".index_table" And I should not see "Mystery" within ".index_table" + And I should see current filter "posts_author_id_eq" equal to "Jane Doe" @javascript Scenario: Clearing filter preserves custom parameters @@ -160,6 +163,7 @@ Feature: Index Filtering And I should see "Mystery" within ".index_table" And I should see "Non-Fiction" within ".index_table" And the "Jane Doe" checkbox should not be checked + And should not see a sidebar titled "Search Status:" Scenario: Checkboxes - Filtering categories via posts written by Jane Doe Given a category named "Mystery" exists diff --git a/features/step_definitions/filter_steps.rb b/features/step_definitions/filter_steps.rb index 2ad7fe49d73..335ada753ac 100644 --- a/features/step_definitions/filter_steps.rb +++ b/features/step_definitions/filter_steps.rb @@ -37,3 +37,8 @@ end end end + +Then /^I should see current filter "([^"]*)" equal to "([^"]*)"( with label "([^"]*)")?$/ do |name, value, label_block, label| + expect(page).to have_css "li.current_filter_#{name} span", text: label if label_block + expect(page).to have_css "li.current_filter_#{name} b", text: value +end \ No newline at end of file diff --git a/lib/active_admin/filters/active.rb b/lib/active_admin/filters/active.rb index dfb41c31fa4..8775c5578ee 100644 --- a/lib/active_admin/filters/active.rb +++ b/lib/active_admin/filters/active.rb @@ -1,22 +1,24 @@ -require 'active_admin/filters/humanized' +require 'active_admin/filters/active_filter' module ActiveAdmin module Filters class Active - attr_accessor :filters + attr_accessor :filters, :resource - def initialize(resource_class, params) - @resource_class = resource_class - @params = params.to_unsafe_h - @filters = build_filters + # Instantiate a `Active` object containing collection of current active filters + + # @param [ActiveAdmin::Resource] current resource + # @param [Ransack::Search] search object, see ActiveAdmin::ResourceController::DataAcces#apply_filtering + def initialize(resource, search) + @resource = resource + @filters = build_filters(search.conditions) end private - def build_filters - filters = @params['q'] || [] - filters.map{ |param| Humanized.new(param) } + def build_filters(conditions) + conditions.map { |condition| ActiveFilter.new(resource, condition.dup) } end end diff --git a/lib/active_admin/filters/active_filter.rb b/lib/active_admin/filters/active_filter.rb new file mode 100644 index 00000000000..a1826390411 --- /dev/null +++ b/lib/active_admin/filters/active_filter.rb @@ -0,0 +1,75 @@ +module ActiveAdmin + module Filters + + class ActiveFilter + include ActiveAdmin::ViewHelpers + + attr_reader :resource, :condition, :related_class + + # Instantiate a `ActiveFilter` + # + # @param [ActiveAdmin::Resource] current resource + # @param [Ransack::Nodes::Condition] applied ransack condition + def initialize(resource, condition) + @resource = resource + @condition = condition + @related_class = find_class + end + + def values + condition_values = condition.values.map(&:value) + if related_class + related_class.find(condition_values) + else + condition_values + end + end + + def label + if related_class + related_class.model_name.human + else + "#{attribute_name} #{predicate_name}".strip + end + end + + def html_options + { class: "current_filter current_filter_#{condition.key}" } + end + + private + + def resource_class + resource.resource_class + end + + def attribute_name + resource_class.human_attribute_name(name) + end + + #@return Ransack::Nodes::Attribute + def condition_attribute + condition.attributes[0] + end + + def name + condition_attribute.attr_name + end + + # translated predicated (equals, contains, etc) + def predicate_name + Ransack::Translate.predicate(condition.predicate.name) + end + + # detect related class for Ransack::Nodes::Attribute + def find_class + if condition_attribute.klass != resource_class && condition_attribute.klass.primary_key == name.to_s + condition_attribute.klass + else + assoc = condition_attribute.klass.reflect_on_all_associations.detect { |r| r.foreign_key == name.to_s } + assoc.class_name.constantize if assoc + end + end + end + end +end diff --git a/lib/active_admin/filters/humanized.rb b/lib/active_admin/filters/humanized.rb deleted file mode 100644 index d608c22f042..00000000000 --- a/lib/active_admin/filters/humanized.rb +++ /dev/null @@ -1,68 +0,0 @@ -module ActiveAdmin - module Filters - - class Humanized - include ActiveAdmin::ViewHelpers - - def initialize(param) - @body = param[0] - @value = param[1] - end - - def value - @value.is_a?(::Array) ? @value.compact.join(', ') : @value - end - - def body - predicate = ransack_predicate_translation - - if current_predicate.nil? - predicate = @body.titleize - elsif translation_missing?(predicate) - predicate = active_admin_predicate_translation - end - - "#{parse_parameter_body} #{predicate}".strip - end - - private - - def parse_parameter_body - return if current_predicate.nil? - - # Accounting for strings that might contain other predicates. Example: - # 'requires_approval' contains the substring 'eq' - split_string = "_#{current_predicate}" - - @body.split(split_string) - .first - .gsub('_', ' ') - .strip - .titleize - .gsub('Id', 'ID') - end - - def current_predicate - @current_predicate ||= predicates.detect { |p| @body.end_with?("_#{p}") } - end - - def predicates - Ransack::Predicate.names_by_decreasing_length - end - - def ransack_predicate_translation - I18n.t("ransack.predicates.#{current_predicate}") - end - - def active_admin_predicate_translation - translation = I18n.t("active_admin.filters.predicates.#{current_predicate}").downcase - end - - def translation_missing?(predicate) - predicate.downcase.include?('translation missing') - end - - end - - end -end diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index 118e10ef4db..c3d2f7e7017 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -153,15 +153,13 @@ def add_search_status_sidebar_section def search_status_section ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.headline"), only: :index, if: -> {active_admin_config.current_filters_enabled? && (params[:q] || params[:scope]) } do - active = ActiveAdmin::Filters::Active.new(resource_class, params) + active = ActiveAdmin::Filters::Active.new(active_admin_config, assigns[:search]) span do - if active_admin_config.scopes.any? h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline' b scope_name(current_scope), class: 'current_scope_name', style: "display: inline" end - div style: "margin-top: 10px" do h4 I18n.t("active_admin.search_status.current_filters"), style: 'margin-bottom: 10px' ul do @@ -169,13 +167,18 @@ def search_status_section li I18n.t("active_admin.search_status.no_current_filters") else active.filters.each do |filter| - li do - span filter.body - b filter.value + li filter.html_options do + span do + text_node filter.label + end + b do + filter.values.map { |value| pretty_format(value) }.join(', ') + end end end end end + end end end diff --git a/spec/unit/filters/active_filter_spec.rb b/spec/unit/filters/active_filter_spec.rb new file mode 100644 index 00000000000..bdb2e6b02f4 --- /dev/null +++ b/spec/unit/filters/active_filter_spec.rb @@ -0,0 +1,90 @@ +require 'rails_helper' + +RSpec.describe ActiveAdmin::Filters::ActiveFilter do + + let(:namespace) do + ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) + end + + let(:resource) do + namespace.register(Post) + end + + let(:user){ User.create! first_name: "John", last_name: "Doe" } + let(:category){ Category.create! name: "Category" } + let(:post){ Post.create! title: "Hello World", category: category, author: user } + + let(:search) do + Post.ransack(title_equals: post.title) + end + + let(:condition) do + search.conditions[0] + end + + subject do + ActiveAdmin::Filters::ActiveFilter.new(resource, condition) + end + + it 'should have valid values' do + expect(subject.values).to eq([post.title]) + end + + it 'should have valid label' do + expect(subject.label).to eq("Title equals") + end + + context 'search by belongs_to association' do + let(:search) do + Post.ransack(custom_category_id_eq: category.id) + end + + it 'should have valid values' do + expect(subject.values[0]).to be_a(Category) + end + + it 'should have valid label' do + expect(subject.label).to eq("Category") + end + + end + + context 'search by has many association' do + let(:resource) do + namespace.register(Category) + end + + let(:search) do + Category.ransack(posts_id_eq: post.id) + end + + it 'should have valid values' do + expect(subject.values[0]).to be_a(Post) + end + + it 'should have valid label' do + expect(subject.label).to eq("Post") + end + + context 'search by has many through association' do + let(:resource) do + namespace.register(User) + end + + let(:search) do + User.ransack(posts_category_id_eq: category.id) + end + + it 'should have valid values' do + expect(subject.values[0]).to be_a(Category) + end + + it 'should have valid label' do + expect(subject.label).to eq("Category") + end + + end + + end + +end \ No newline at end of file diff --git a/spec/unit/filters/active_spec.rb b/spec/unit/filters/active_spec.rb index 79eb243b1b3..c839767f31f 100644 --- a/spec/unit/filters/active_spec.rb +++ b/spec/unit/filters/active_spec.rb @@ -1,12 +1,22 @@ require 'rails_helper' RSpec.describe ActiveAdmin::Filters::Active do - subject { described_class.new(Post, params) } + + let(:resource) do + namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) + namespace.register(Post) + end + + subject { described_class.new(resource, search) } let(:params) do ::ActionController::Parameters.new(q: {author_id_eq: 1}) end + let(:search) do + Post.ransack(params[:q]) + end + it 'should have filters' do expect(subject.filters.size).to eq(1) end diff --git a/spec/unit/filters/humanized_spec.rb b/spec/unit/filters/humanized_spec.rb deleted file mode 100644 index 4204d2326ea..00000000000 --- a/spec/unit/filters/humanized_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'rails_helper' - -RSpec.describe ActiveAdmin::Filters::Humanized do - describe '#value' do - it 'should equal query string parameter if not an Array' do - param = ['category_id_eq', '1'] - subject = ActiveAdmin::Filters::Humanized.new(param) - expect(subject.value).to eq('1') - end - - it 'should equal query string parameters separated by commas if an Array' do - param = ['category_id_eq', ['1', '2']] - subject = ActiveAdmin::Filters::Humanized.new(param) - expect(subject.value).to eq("1, 2") - end - - it 'should remove nil values before joining equal query string parameters separated by commas if an Array' do - param = ['category_id_eq', ['1', nil, '2']] - subject = ActiveAdmin::Filters::Humanized.new(param) - expect(subject.value).to eq("1, 2") - end - end - - describe '#body' do - context 'when Ransack predicate' do - it 'parses language from Ransack' do - param = ['category_id_eq', '1'] - subject = ActiveAdmin::Filters::Humanized.new(param) - expect(subject.body).to eq('Category ID equals') - end - - it 'handles strings with embedded predicates' do - param = ['requires_approval_eq', '1'] - humanizer = ActiveAdmin::Filters::Humanized.new(param) - expect(humanizer.value).to eq('1') - expect(humanizer.body).to eq('Requires Approval equals') - end - end - - context 'when ActiveAdmin predicate' do - it 'parses language from ActiveAdmin' do - param = ['name_starts_with', 'test'] - humanizer = ActiveAdmin::Filters::Humanized.new(param) - expect(humanizer.body).to eq('Name starts with') - end - end - - context 'when unknown predicate' do - it 'uses raw predicate string' do - param = ['name_predicate_does_not_exist', 'test'] - humanizer = ActiveAdmin::Filters::Humanized.new(param) - expect(humanizer.body).to eq("Name Predicate Does Not Exist") - end - end - - context 'when column name similar to predicate' do - it 'parses correct predicate' do - param = ['time_start_gteq', 'test'] - humanizer = ActiveAdmin::Filters::Humanized.new(param) - expect(humanizer.body).to eq('Time Start greater than or equal to') - end - end - end -end From 929008b023dbe8ca19bc0c7f2d9452286f85b570 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 11 May 2017 13:30:10 +0300 Subject: [PATCH 0535/3836] fixed pretty_format rendering for objects in active filter sidebar --- features/index/filters.feature | 20 ++++++++++++++++++- features/step_definitions/filter_steps.rb | 4 ++++ lib/active_admin/filters/active_filter.rb | 4 ++-- .../filters/resource_extension.rb | 2 +- spec/unit/filters/active_filter_spec.rb | 6 +++--- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/features/index/filters.feature b/features/index/filters.feature index 77789394a7c..9377f78d82e 100644 --- a/features/index/filters.feature +++ b/features/index/filters.feature @@ -173,6 +173,7 @@ Feature: Index Filtering ActiveAdmin.register Category do filter :authors, as: :check_boxes end + """ When I check "Jane Doe" And I press "Filter" @@ -180,6 +181,23 @@ Feature: Index Filtering And I should see "Non-Fiction" within ".index_table" And the "Jane Doe" checkbox should be checked + Scenario: Filtering posts by category + Given a category named "Mystery" exists + And a post with the title "Hello World" written by "Jane Doe" in category "Non-Fiction" exists + Given an index configuration of: + """ + ActiveAdmin.register Category + ActiveAdmin.register Post do + filter :category + end + """ + And I am on the index page for posts + + When I select "Non-Fiction" from "Category" + And I press "Filter" + Then I should see a sidebar titled "Search Status:" + And I should see link "Non-Fiction" in current filters + Scenario: Enabling filters status sidebar Given an index configuration of: """ @@ -200,4 +218,4 @@ Feature: Index Filtering end """ And I press "Filter" - Then I should not see a sidebar titled "Search Status:" \ No newline at end of file + Then I should not see a sidebar titled "Search Status:" diff --git a/features/step_definitions/filter_steps.rb b/features/step_definitions/filter_steps.rb index 335ada753ac..c7b1fdecfba 100644 --- a/features/step_definitions/filter_steps.rb +++ b/features/step_definitions/filter_steps.rb @@ -41,4 +41,8 @@ Then /^I should see current filter "([^"]*)" equal to "([^"]*)"( with label "([^"]*)")?$/ do |name, value, label_block, label| expect(page).to have_css "li.current_filter_#{name} span", text: label if label_block expect(page).to have_css "li.current_filter_#{name} b", text: value +end + +Then /^I should see link "([^"]*)" in current filters/ do |label| + expect(page).to have_css "li.current_filter b a", text: label end \ No newline at end of file diff --git a/lib/active_admin/filters/active_filter.rb b/lib/active_admin/filters/active_filter.rb index a1826390411..4ca1f71125a 100644 --- a/lib/active_admin/filters/active_filter.rb +++ b/lib/active_admin/filters/active_filter.rb @@ -27,7 +27,7 @@ def values def label if related_class - related_class.model_name.human + "#{related_class.model_name.human} #{predicate_name}".strip else "#{attribute_name} #{predicate_name}".strip end @@ -66,7 +66,7 @@ def find_class if condition_attribute.klass != resource_class && condition_attribute.klass.primary_key == name.to_s condition_attribute.klass else - assoc = condition_attribute.klass.reflect_on_all_associations.detect { |r| r.foreign_key == name.to_s } + assoc = condition_attribute.klass.reflect_on_all_associations.detect { |r| r.foreign_key.to_s == name.to_s } assoc.class_name.constantize if assoc end end diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index c3d2f7e7017..cc7928c7d95 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -172,7 +172,7 @@ def search_status_section text_node filter.label end b do - filter.values.map { |value| pretty_format(value) }.join(', ') + text_node filter.values.map{|v| pretty_format(v) }.to_sentence.html_safe end end end diff --git a/spec/unit/filters/active_filter_spec.rb b/spec/unit/filters/active_filter_spec.rb index bdb2e6b02f4..43a8db96ff5 100644 --- a/spec/unit/filters/active_filter_spec.rb +++ b/spec/unit/filters/active_filter_spec.rb @@ -44,7 +44,7 @@ end it 'should have valid label' do - expect(subject.label).to eq("Category") + expect(subject.label).to eq("Category equals") end end @@ -63,7 +63,7 @@ end it 'should have valid label' do - expect(subject.label).to eq("Post") + expect(subject.label).to eq("Post equals") end context 'search by has many through association' do @@ -80,7 +80,7 @@ end it 'should have valid label' do - expect(subject.label).to eq("Category") + expect(subject.label).to eq("Category equals") end end From 3eb5f95b4d28e81d2cfae420dc3ce41155ca938a Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Tue, 23 May 2017 17:43:59 +0300 Subject: [PATCH 0536/3836] move current filters sidebar to it's own class --- lib/active_admin/filters.rb | 2 + lib/active_admin/filters/active_sidebar.rb | 51 +++++++++++++++++++ .../filters/resource_extension.rb | 38 +------------- 3 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 lib/active_admin/filters/active_sidebar.rb diff --git a/lib/active_admin/filters.rb b/lib/active_admin/filters.rb index 13485d79232..0306040fbee 100644 --- a/lib/active_admin/filters.rb +++ b/lib/active_admin/filters.rb @@ -2,6 +2,8 @@ require 'active_admin/filters/resource_extension' require 'active_admin/filters/formtastic_addons' require 'active_admin/filters/forms' +require 'active_admin/helpers/optional_display' +require 'active_admin/filters/active_sidebar' # Add our Extensions ActiveAdmin::ResourceDSL.send :include, ActiveAdmin::Filters::DSL diff --git a/lib/active_admin/filters/active_sidebar.rb b/lib/active_admin/filters/active_sidebar.rb new file mode 100644 index 00000000000..bf89081bd38 --- /dev/null +++ b/lib/active_admin/filters/active_sidebar.rb @@ -0,0 +1,51 @@ +require 'active_admin/filters/active' + +module ActiveAdmin + module Filters + class ActiveSidebar < ActiveAdmin::SidebarSection + + def initialize + super I18n.t("active_admin.search_status.headline"), sidebar_options + end + + def block + -> do + active_filters = ActiveAdmin::Filters::Active.new(active_admin_config, assigns[:search]) + span do + if active_admin_config.scopes.any? + h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline' + b scope_name(current_scope), class: 'current_scope_name', style: "display: inline" + end + div style: "margin-top: 10px" do + h4 I18n.t("active_admin.search_status.current_filters"), style: 'margin-bottom: 10px' + ul do + if active_filters.filters.blank? + li I18n.t("active_admin.search_status.no_current_filters") + else + active_filters.filters.each do |filter| + li filter.html_options do + span do + text_node filter.label + end + b do + text_node filter.values.map { |v| pretty_format(v) }.to_sentence.html_safe + end + end + end + end + end + end + end + end + end + + protected + + def sidebar_options + { only: :index, if: -> { active_admin_config.current_filters_enabled? && (params[:q] || params[:scope]) } } + end + + end + end +end + diff --git a/lib/active_admin/filters/resource_extension.rb b/lib/active_admin/filters/resource_extension.rb index cc7928c7d95..70d4a1e24ce 100644 --- a/lib/active_admin/filters/resource_extension.rb +++ b/lib/active_admin/filters/resource_extension.rb @@ -1,5 +1,3 @@ -require 'active_admin/filters/active' - module ActiveAdmin module Filters @@ -148,41 +146,9 @@ def filters_sidebar_section end def add_search_status_sidebar_section - self.sidebar_sections << search_status_section - end - - def search_status_section - ActiveAdmin::SidebarSection.new I18n.t("active_admin.search_status.headline"), only: :index, if: -> {active_admin_config.current_filters_enabled? && (params[:q] || params[:scope]) } do - active = ActiveAdmin::Filters::Active.new(active_admin_config, assigns[:search]) - - span do - if active_admin_config.scopes.any? - h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline' - b scope_name(current_scope), class: 'current_scope_name', style: "display: inline" - end - div style: "margin-top: 10px" do - h4 I18n.t("active_admin.search_status.current_filters"), style: 'margin-bottom: 10px' - ul do - if active.filters.blank? - li I18n.t("active_admin.search_status.no_current_filters") - else - active.filters.each do |filter| - li filter.html_options do - span do - text_node filter.label - end - b do - text_node filter.values.map{|v| pretty_format(v) }.to_sentence.html_safe - end - end - end - end - end - - end - end - end + self.sidebar_sections << ActiveAdmin::Filters::ActiveSidebar.new end + end end From d8fd950357baf702de304c1ce9e30e1a8290fdd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Ferrandis?= Date: Thu, 1 Jun 2017 15:44:59 +0200 Subject: [PATCH 0537/3836] Add datetime filter predicates translations to fr.yml --- config/locales/fr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 34097723b5a..55315185ae9 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -31,6 +31,8 @@ fr: ends_with: "Se termine par" greater_than: "Plus grand que" less_than: "Plus petit que" + gteq_datetime: "Ultérieur ou égal à" + lteq_datetime: "Antérieur ou égal à" search_status: headline: "Statut de la recherche :" current_scope: "Etendu du filtre :" From f497815e8fd8a994468231d94f946f18d9866b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Ferrandis?= Date: Thu, 1 Jun 2017 15:49:43 +0200 Subject: [PATCH 0538/3836] Add datetime filter predicates translations to en.yml --- config/locales/en.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 54dee0be24f..f6fbf080d11 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -32,6 +32,8 @@ en: ends_with: "Ends with" greater_than: "Greater than" less_than: "Less than" + gteq_datetime: "Greater or equal to" + lteq_datetime: "Lesser or equal to" search_status: headline: "Search status:" current_scope: "Scope:" From 7ec7d2f3fe603ec3069174986ef6c9f5a837cef3 Mon Sep 17 00:00:00 2001 From: Andrei Date: Fri, 2 Jun 2017 13:21:06 +0300 Subject: [PATCH 0539/3836] Include Authorization in BaseController before Menu to be able to use authorization methods in navigation_menu block --- lib/active_admin/base_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/base_controller.rb b/lib/active_admin/base_controller.rb index 2740408e633..f083b664443 100644 --- a/lib/active_admin/base_controller.rb +++ b/lib/active_admin/base_controller.rb @@ -29,8 +29,8 @@ def only_render_implemented_actions raise AbstractController::ActionNotFound unless action_methods.include?(params[:action]) end - include Menu include Authorization + include Menu private From 7c14dc39892dedb5560c2a2df828b69ad2b96afd Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Sat, 3 Jun 2017 11:16:58 -0400 Subject: [PATCH 0540/3836] Remove unnecessary br tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Causing excessive bottom padding in login panel (logged_out view) and can’t control through CSS. --- app/views/active_admin/devise/shared/_links.erb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/active_admin/devise/shared/_links.erb b/app/views/active_admin/devise/shared/_links.erb index 9daf5702436..63813da717f 100644 --- a/app/views/active_admin/devise/shared/_links.erb +++ b/app/views/active_admin/devise/shared/_links.erb @@ -1,27 +1,27 @@ <%- if controller_name != 'sessions' %> <% scope = Devise::Mapping.find_scope!(resource_name) %> - <%= link_to t('active_admin.devise.links.sign_in'), send(:"new_#{scope}_session_path") %>
      + <%= link_to t('active_admin.devise.links.sign_in'), send(:"new_#{scope}_session_path") %> <% end -%> <%- if devise_mapping.registerable? && controller_name != 'registrations' %> - <%= link_to t('active_admin.devise.links.sign_up'), new_registration_path(resource_name) %>
      + <%= link_to t('active_admin.devise.links.sign_up'), new_registration_path(resource_name) %> <% end -%> <%- if devise_mapping.recoverable? && controller_name != 'passwords' %> - <%= link_to t('active_admin.devise.links.forgot_your_password'), new_password_path(resource_name) %>
      + <%= link_to t('active_admin.devise.links.forgot_your_password'), new_password_path(resource_name) %> <% end -%> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> - <%= link_to t('active_admin.devise.links.resend_confirmation_instructions'), new_confirmation_path(resource_name) %>
      + <%= link_to t('active_admin.devise.links.resend_confirmation_instructions'), new_confirmation_path(resource_name) %> <% end -%> <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> - <%= link_to t('active_admin.devise.links.resend_unlock_instructions'), new_unlock_path(resource_name) %>
      + <%= link_to t('active_admin.devise.links.resend_unlock_instructions'), new_unlock_path(resource_name) %> <% end -%> <%- if devise_mapping.omniauthable? %> <%- resource_class.omniauth_providers.each do |provider| %> <%= link_to t('active_admin.devise.links.sign_in_with_omniauth_provider', provider: provider.to_s.titleize), - omniauth_authorize_path(resource_name, provider) %>
      + omniauth_authorize_path(resource_name, provider) %> <% end -%> <% end -%> From 2e387743ddce7fe6bff0f6881e32f75ab3b94f1e Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Sat, 3 Jun 2017 11:26:16 -0400 Subject: [PATCH 0541/3836] Add indeterminate support if some checkboxes are checked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A nice visual enhancement that shows the toggle all checkbox in an indeterminate state which is visual only (similar to GitHub for Mac or Gmail web). I have a jQuery plugin I’m working for this behavior so I’m already familiar with what to add. For more info: https://css-tricks.com/indeterminate-checkboxes/ Performance improvements as there is no need to loop over checkboxes to set checked property, the prop method will work on a collection. Further the loop was needed to trigger didChangeCheckbox method for the table-checkbox-toggler sub class but the better way is for that subclass to override the didChangeToggleAllCheckbox otherwise you’re calling didChangeCheckbox for every checkbox and running DOM queries and updates that are unnecessary. Existing behavior preserved as all tests are passing. --- .../active_admin/lib/checkbox-toggler.js.coffee | 16 +++++++++------- .../lib/table-checkbox-toggler.js.coffee | 8 ++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee b/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee index 4b7800b59a6..78bde365504 100644 --- a/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee +++ b/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee @@ -23,15 +23,17 @@ class ActiveAdmin.CheckboxToggler @toggle_all_checkbox.change => @_didChangeToggleAllCheckbox() _didChangeCheckbox: (checkbox)-> - switch @checkboxes.filter(':checked').length - when @checkboxes.length - 1 then @toggle_all_checkbox.prop checked: null - when @checkboxes.length then @toggle_all_checkbox.prop checked: true + numChecked = @checkboxes.filter(':checked').length + + allChecked = numChecked == @checkboxes.length + someChecked = numChecked > 0 && numChecked < @checkboxes.length + + @toggle_all_checkbox.prop checked: allChecked, indeterminate: someChecked _didChangeToggleAllCheckbox: -> - setting = if @toggle_all_checkbox.prop 'checked' then true else null - @checkboxes.each (index, el)=> - $(el).prop checked: setting - @_didChangeCheckbox(el) + setting = @toggle_all_checkbox.prop 'checked' + @checkboxes.prop checked: setting + setting option: (key, value) -> if $.isPlainObject(key) diff --git a/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee b/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee index 25ec31c5877..2ba5f2dc880 100644 --- a/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee +++ b/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee @@ -18,6 +18,14 @@ class ActiveAdmin.TableCheckboxToggler extends ActiveAdmin.CheckboxToggler else $row.removeClass 'selected' + _didChangeToggleAllCheckbox: -> + checked = super + + if checked + @$container.find('tbody tr').addClass 'selected' + else + @$container.find('tbody tr').removeClass 'selected' + _didClickCell: (cell) -> $(cell).parent('tr').find(':checkbox').click() From 4c49e61ac93b650af6a287c7a8f667fd51a70ed1 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Sat, 3 Jun 2017 11:27:30 -0400 Subject: [PATCH 0542/3836] Use jQuery's toggleClass method --- .../lib/table-checkbox-toggler.js.coffee | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee b/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee index 2ba5f2dc880..ae4bd4b1d8a 100644 --- a/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee +++ b/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee @@ -11,20 +11,10 @@ class ActiveAdmin.TableCheckboxToggler extends ActiveAdmin.CheckboxToggler _didChangeCheckbox: (checkbox) -> super - $row = $(checkbox).parents 'tr' - - if checkbox.checked - $row.addClass 'selected' - else - $row.removeClass 'selected' + $(checkbox).parents('tr').toggleClass 'selected', checkbox.checked _didChangeToggleAllCheckbox: -> - checked = super - - if checked - @$container.find('tbody tr').addClass 'selected' - else - @$container.find('tbody tr').removeClass 'selected' + @$container.find('tbody tr').toggleClass 'selected', super _didClickCell: (cell) -> $(cell).parent('tr').find(':checkbox').click() From d85511057958a06bdb1bb465483cd8f15c59c670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 3 Jun 2017 13:41:11 -0300 Subject: [PATCH 0543/3836] Test against latest jruby --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7517171c12a..25589f8639d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ script: - bundle exec rake rvm: - - jruby-9.1.8.0 + - jruby-9.1.10.0 - 2.1.10 - 2.2.7 - 2.3.4 @@ -49,9 +49,9 @@ matrix: gemfile: gemfiles/rails_51.gemfile allow_failures: - - rvm: jruby-9.1.8.0 + - rvm: jruby-9.1.10.0 gemfile: gemfiles/rails_50.gemfile - - rvm: jruby-9.1.8.0 + - rvm: jruby-9.1.10.0 gemfile: gemfiles/rails_51.gemfile notifications: From 484a0515b2f48a16dd511d60737801cdc4c65209 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Sat, 3 Jun 2017 19:11:18 -0400 Subject: [PATCH 0544/3836] Deprecate the `type` param in `status_tag` and related CSS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can provide existing functionality here pretty easily so we’ll deprecate the type param and update our unit tests to suppress the warning. The tests for the specific type param check the warning message to make sure its formatted right. Added changelog for `status_tag` breaking change. Updated examples in documentation. Providing a more detailed deprecation message. When given a type of “ok” the output from running the code in a console is: ``` DEPRECATION WARNING: Active Admin: The `type` parameter has been deprecated. Provide the "ok" type as a class instead. For example, `status_tag(status, :ok, class: "abc")` would change to `status_tag(status, class: "ok abc")`. Also note that the "ok" CSS rule will be removed too, so you'll have to provide the styles yourself. See https://github.com/activeadmin/activeadmin/blob/master/CHANGELOG.md#110- for more information. ``` --- CHANGELOG.md | 21 ++++++++++++- .../active_admin/components/_status_tags.scss | 1 + docs/12-arbre-components.md | 11 +++---- .../views/components/status_tag.rb | 26 ++++++++++------ spec/unit/views/components/status_tag_spec.rb | 30 ++++++++++++++----- 5 files changed, 65 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9d74a04294..ee37c3a786c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ ## Master (unreleased) +### Deprecations + +* Deprecated `type` param from `status_tag` and related CSS classes [#4989][] by [@javierjulio][] + * The method signature has changed from: + ```ruby + status_tag(status, :ok, class: 'completed', label: 'on') + # now changes to: + status_tag(status, class: 'completed ok', label: 'on') + ``` + * The following CSS classes have been deprecated and will be removed in the future: + ```css + .status_tag { + &.ok, &.published, &.complete, &.completed, &.green { background: #8daa92; } + &.warn, &.warning, &.orange { background: #e29b20; } + &.error, &.errored, &.red { background: #d45f53; } + } + ``` + + ### Enhancements ##### Minor @@ -69,7 +88,7 @@ index download_links: ->{ can?(:view_all_download_links) || [:pdf] } ### Security Fixes -* Prevents access to formats that the user not permitted to see [#4867][] by [@Fivell][] and [@timoschilling][] +* Prevents access to formats that the user not permitted to see [#4867][] by [@Fivell][] and [@timoschilling][] * Prevents potential DOS attack via Ruby symbols [#1926][] by [@seanlinsley][] * [this isn't an issue for those using Ruby >= 2.2](http://rubykaigi.org/2014/presentation/S-NarihiroNakamura) diff --git a/app/assets/stylesheets/active_admin/components/_status_tags.scss b/app/assets/stylesheets/active_admin/components/_status_tags.scss index 77b02e3d67b..dc1b9b9fb60 100644 --- a/app/assets/stylesheets/active_admin/components/_status_tags.scss +++ b/app/assets/stylesheets/active_admin/components/_status_tags.scss @@ -6,6 +6,7 @@ padding: 3px 5px 2px 5px; font-size: 0.8em; + // TODO: deprecated, remove in a v2 release &.ok, &.published, &.complete, &.completed, &.green { background: #8daa92; } &.warn, &.warning, &.orange { background: #e29b20; } &.error, &.errored, &.red { background: #d45f53; } diff --git a/docs/12-arbre-components.md b/docs/12-arbre-components.md index 1afe9763382..84dfe8dfefd 100644 --- a/docs/12-arbre-components.md +++ b/docs/12-arbre-components.md @@ -138,18 +138,15 @@ takes a block. Status tags provide convenient syntactic sugar for styling items that have status. A common example of where the status tag could be useful is for orders that are complete or in progress. `status_tag` takes a status, like -"In Progress", a type, which defaults to nil, and a hash of options. The -status_tag will generate html markup that Active Admin css uses in styling. +"In Progress", and a hash of options. The status_tag will generate HTML markup +that Active Admin CSS uses in styling. ```ruby status_tag 'In Progress' # => In Progress -status_tag 'active', :ok -# => Active - -status_tag 'active', :ok, class: 'important', id: 'status_123', label: 'on' -# => on +status_tag 'active', class: 'important', id: 'status_123', label: 'on' +# => on ``` ## Tabs diff --git a/lib/active_admin/views/components/status_tag.rb b/lib/active_admin/views/components/status_tag.rb index 54006f0f065..1f9ceef68f9 100644 --- a/lib/active_admin/views/components/status_tag.rb +++ b/lib/active_admin/views/components/status_tag.rb @@ -12,9 +12,8 @@ def default_class_name 'status_tag' end - # @overload status_tag(status, type = nil, options = {}) + # @overload status_tag(status, options = {}) # @param [String] status the status to display. One of the span classes will be an underscored version of the status. - # @param [Symbol] type type of status. Will become a class of the span. ActiveAdmin provide style for :ok, :warning and :error. # @param [Hash] options # @option options [String] :class to override the default class # @option options [String] :id to override the default id @@ -26,17 +25,14 @@ def default_class_name # # => In Progress # # @example - # status_tag('active', :ok) - # # => Active - # - # @example - # status_tag('active', :ok, class: 'important', id: 'status_123', label: 'on') - # # => on + # status_tag('active', class: 'important', id: 'status_123', label: 'on') + # # => on # def build(*args) options = args.extract_options! status = args[0] type = args[1] + label = options.delete(:label) classes = options.delete(:class) status = convert_to_boolean_status(status) @@ -50,7 +46,19 @@ def build(*args) super(content, options) add_class(status_to_class(status)) if status - add_class(type.to_s) if type + + if type + Deprecation.warn <<-MSG.strip_heredoc + The `type` parameter has been deprecated. Provide the "#{type}" type as + a class instead. For example, `status_tag(status, :#{type}, class: "abc")` + would change to `status_tag(status, class: "#{type} abc")`. Also note that + the "#{type}" CSS rule will be removed too, so you'll have to provide + the styles yourself. See https://github.com/activeadmin/activeadmin/blob/master/CHANGELOG.md#110- + for more information. + MSG + add_class(type.to_s) + end + add_class(classes) if classes end diff --git a/spec/unit/views/components/status_tag_spec.rb b/spec/unit/views/components/status_tag_spec.rb index 3485ff21fe1..c069d9d5c21 100644 --- a/spec/unit/views/components/status_tag_spec.rb +++ b/spec/unit/views/components/status_tag_spec.rb @@ -134,17 +134,38 @@ def status_tag(*args) context "when status is 'Active' and type is :ok" do subject { status_tag('Active', :ok) } + describe 'is deprecated' do + subject { super().class_list } + it do + expect(ActiveAdmin::Deprecation) + .to receive(:warn) + .with(<<-MSG.strip_heredoc + The `type` parameter has been deprecated. Provide the "ok" type as + a class instead. For example, `status_tag(status, :ok, class: "abc")` + would change to `status_tag(status, class: "ok abc")`. Also note that + the "ok" CSS rule will be removed too, so you'll have to provide + the styles yourself. See https://github.com/activeadmin/activeadmin/blob/master/CHANGELOG.md#110- + for more information. + MSG + ) + is_expected.to include('ok') + end + end + describe '#class_list' do + before { expect(ActiveAdmin::Deprecation).to receive(:warn).once } subject { super().class_list } it { is_expected.to include('status_tag') } end describe '#class_list' do + before { expect(ActiveAdmin::Deprecation).to receive(:warn).once } subject { super().class_list } it { is_expected.to include('active') } end describe '#class_list' do + before { expect(ActiveAdmin::Deprecation).to receive(:warn).once } subject { super().class_list } it { is_expected.to include('ok') } end @@ -193,8 +214,8 @@ def status_tag(*args) end end - context "when status is 'So useless', type is :ok, class is 'woot awesome' and id is 'useless'" do - subject { status_tag('So useless', :ok, class: 'woot awesome', id: 'useless') } + context "when status is 'So useless', class is 'woot awesome' and id is 'useless'" do + subject { status_tag('So useless', class: 'woot awesome', id: 'useless') } describe '#content' do subject { super().content } @@ -206,11 +227,6 @@ def status_tag(*args) it { is_expected.to include('status_tag') } end - describe '#class_list' do - subject { super().class_list } - it { is_expected.to include('ok') } - end - describe '#class_list' do subject { super().class_list } it { is_expected.to include('so_useless') } From 7f40a2e2415178d751ac410f70533bb7d054ad63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 6 Jun 2017 17:39:15 -0300 Subject: [PATCH 0545/3836] Bump rubocop version --- .rubocop.yml | 20 ++++++++++---------- Gemfile | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index d0d2510aa66..d41ae6ee008 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -20,28 +20,28 @@ AllCops: Lint/EndAlignment: Enabled: true -Style/CaseIndentation: +Layout/CaseIndentation: Enabled: true -Style/ElseAlignment: +Layout/ElseAlignment: Enabled: true -Style/EmptyLines: +Layout/EmptyLines: Enabled: true -Style/EndOfLine: +Layout/EndOfLine: Enabled: true -Style/ExtraSpacing: +Layout/ExtraSpacing: Enabled: true Style/HashSyntax: Enabled: true -Style/IndentationConsistency: +Layout/IndentationConsistency: Enabled: true -Style/IndentationWidth: +Layout/IndentationWidth: Enabled: true Style/PredicateName: @@ -55,11 +55,11 @@ Style/PredicateName: - has_many - has_many_actions -Style/TrailingWhitespace: +Layout/TrailingWhitespace: Enabled: true -Style/SpaceAfterComma: +Layout/SpaceAfterComma: Enabled: true -Style/SpaceInsideParens: +Layout/SpaceInsideParens: Enabled: true diff --git a/Gemfile b/Gemfile index 52dc617a8fd..6e7b79681d7 100644 --- a/Gemfile +++ b/Gemfile @@ -19,7 +19,7 @@ gem 'parallel_tests' gem 'pry' # Easily debug from your console with `binding.pry` # Code style -gem 'rubocop', '0.48.1' +gem 'rubocop', '0.49.1' # Translations gem 'i18n-tasks' From 775cc85806bfabbc75c87ee4446a9dbfc8bf8033 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Sat, 3 Jun 2017 17:47:42 -0400 Subject: [PATCH 0546/3836] Wrap resource_selection_toggle_cell in a label tag This way the text itself is clickable and toggles the checkbox. No need for additional div wrappers either. --- .../active_admin/components/_batch_actions.scss | 5 ----- .../batch_actions/views/selection_cells.rb | 11 ++++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/app/assets/stylesheets/active_admin/components/_batch_actions.scss b/app/assets/stylesheets/active_admin/components/_batch_actions.scss index 12ad1517474..9a054f6122d 100644 --- a/app/assets/stylesheets/active_admin/components/_batch_actions.scss +++ b/app/assets/stylesheets/active_admin/components/_batch_actions.scss @@ -3,9 +3,4 @@ >.resource_selection_toggle_cell { float:left; } - #collection_selection_toggle_explaination { - float:left; - margin-left:5px; - font-style:italic; - } } diff --git a/lib/active_admin/batch_actions/views/selection_cells.rb b/lib/active_admin/batch_actions/views/selection_cells.rb index 1cc3cf4ac39..fb5c58f51f9 100644 --- a/lib/active_admin/batch_actions/views/selection_cells.rb +++ b/lib/active_admin/batch_actions/views/selection_cells.rb @@ -7,8 +7,11 @@ module BatchActions class ResourceSelectionToggleCell < ActiveAdmin::Component builder_method :resource_selection_toggle_cell - def build - input type: "checkbox", id: "collection_selection_toggle_all", name: "collection_selection_toggle_all", class: "toggle_all" + def build(label_text='') + label do + input type: "checkbox", id: "collection_selection_toggle_all", name: "collection_selection_toggle_all", class: "toggle_all" + text_node label_text if label_text.present? + end end end @@ -27,10 +30,8 @@ class ResourceSelectionTogglePanel < ActiveAdmin::Component def build super(id: "collection_selection_toggle_panel") - resource_selection_toggle_cell - div(id: "collection_selection_toggle_explaination") { I18n.t('active_admin.batch_actions.selection_toggle_explanation', default: "(Toggle Selection)") } + resource_selection_toggle_cell(I18n.t('active_admin.batch_actions.selection_toggle_explanation', default: "(Toggle Selection)")) end - end end From 0ac8a8d31586bcf72df8832e86cecf01f43092ee Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 11:53:59 -0400 Subject: [PATCH 0547/3836] Add space around optional label_text param value --- lib/active_admin/batch_actions/views/selection_cells.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/batch_actions/views/selection_cells.rb b/lib/active_admin/batch_actions/views/selection_cells.rb index fb5c58f51f9..16e927fdcbc 100644 --- a/lib/active_admin/batch_actions/views/selection_cells.rb +++ b/lib/active_admin/batch_actions/views/selection_cells.rb @@ -7,7 +7,7 @@ module BatchActions class ResourceSelectionToggleCell < ActiveAdmin::Component builder_method :resource_selection_toggle_cell - def build(label_text='') + def build(label_text = '') label do input type: "checkbox", id: "collection_selection_toggle_all", name: "collection_selection_toggle_all", class: "toggle_all" text_node label_text if label_text.present? From 41b708852c2b8c99c4f5d37f91ea916c63eb36c4 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Sat, 3 Jun 2017 18:18:25 -0400 Subject: [PATCH 0548/3836] Remove inline separator --- app/assets/stylesheets/active_admin/_forms.scss | 6 ------ lib/active_admin/inputs/filters/date_range_input.rb | 1 - spec/unit/filters/filter_form_builder_spec.rb | 6 ------ 3 files changed, 13 deletions(-) diff --git a/app/assets/stylesheets/active_admin/_forms.scss b/app/assets/stylesheets/active_admin/_forms.scss index 08e0fbd12ac..b0b7dc946e8 100644 --- a/app/assets/stylesheets/active_admin/_forms.scss +++ b/app/assets/stylesheets/active_admin/_forms.scss @@ -326,12 +326,6 @@ form.filter_form { } &.filter_date_range { - .seperator { - display: inline-block; - text-align: center; - width: $filter-field-seperator-width; - } - input[type=text] { background: #fff image-url('active_admin/datepicker/datepicker-input-icon.png') no-repeat 100% 7px; padding-right: $date-range-filter-input-right-padding; diff --git a/lib/active_admin/inputs/filters/date_range_input.rb b/lib/active_admin/inputs/filters/date_range_input.rb index 4fe12dd982a..6b1612db299 100644 --- a/lib/active_admin/inputs/filters/date_range_input.rb +++ b/lib/active_admin/inputs/filters/date_range_input.rb @@ -8,7 +8,6 @@ def to_html input_wrapping do [ label_html, builder.text_field(gt_input_name, input_html_options(gt_input_name)), - template.content_tag(:span, "-", class: "seperator"), builder.text_field(lt_input_name, input_html_options(lt_input_name)), ].join("\n").html_safe end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 9c86986e4b6..750e48537f5 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -165,9 +165,6 @@ def filter(name, options = {}) it "should generate a date greater than" do expect(body).to have_selector("input.datepicker[name='q[published_date_gteq]']") end - it "should generate a seperator" do - expect(body).to have_selector("span.seperator") - end it "should generate a date less than" do expect(body).to have_selector("input.datepicker[name='q[published_date_lteq]']") end @@ -179,9 +176,6 @@ def filter(name, options = {}) it "should generate a date greater than" do expect(body).to have_selector("input.datepicker[name='q[created_at_gteq_datetime]']") end - it "should generate a seperator" do - expect(body).to have_selector("span.seperator") - end it "should generate a date less than" do expect(body).to have_selector("input.datepicker[name='q[created_at_lteq_datetime]']") end From 1e96b956b14e1e045b98c7a285f9e059b303acc3 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Sat, 3 Jun 2017 18:22:35 -0400 Subject: [PATCH 0549/3836] Use "starts/ends with" placeholders for date range fields This is all around a better choice as its descriptive what each field does in place not having a label like other filter fields do. We need to apply box-sizing: border-box on the input so they stay evenly side by side because the width we give it is the width we want it to have. Without that rule, the padding is in addition to the width (meaning 5px horizontal padding and 100px width, then the rendered width is 110px). --- .../datepicker/datepicker-input-icon.png | Bin 1535 -> 0 bytes app/assets/stylesheets/active_admin/_forms.scss | 12 ++++++------ .../inputs/filters/date_range_input.rb | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) delete mode 100644 app/assets/images/active_admin/datepicker/datepicker-input-icon.png diff --git a/app/assets/images/active_admin/datepicker/datepicker-input-icon.png b/app/assets/images/active_admin/datepicker/datepicker-input-icon.png deleted file mode 100644 index 40ad6f74074ef3e705c688416b70c933b01d0316..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1535 zcmeAS@N?(olHy`uVBq!ia0vp^A|N&g8<1QX;1>s^BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFe_z-M3hAM`dB6B=jtVb)aX^@765fKFxc2v6eK2Rr0UTq__OB&@Hb09I0xZL0)vRD^GUf^&XRs)DJWfo`&anSp|tp`M|! ziMhGCj)IYap@F`Ek-njkuA#Y=v5}R5fdUjL0c|TvNwW%aaf8|g1^l#~=$>Fbx5 zm+O@q>*W`v>l<2HT7t|lGSUUA&@HaaD@m--%_~-hnc$LIoLrPyP?DLSrvNfBF)6>a z#8wIDQivCF3*g4)6+?pw7-0Gpi3R$GdIlgb!4&%X;#ZoR3s+rS5|oN?FIIz#Ln;eW z^@CE2^Gl18ff1Lc46>@g%DE^tu_V7JBtJg~7K#BG`6caSW-r z)f0TyJ0wtK|NQ)W()WL)nPi=DIwrY^pZnq!v8@FQS(In6ii$MyBua;`&ANR2kl58l z9U2?z6>dFQ7V3D#>6e4I;BhvoVuRvkg;MfX^6&56mOMS-!a?Teh4*%T|8wr=++w{T zuZ5;>xxSl~mwx~D_xWqq_~TXamZ=3h*^=Kd#V+dE7I@7;U< zeNU}a{LZSk&-P3@RcZJ~r_oH1%|Y;3#D(Xd`z-njmV_u-{e3F%_)p0OyALLIpM4L^ z{P*hX?8S4kt2x~wJEU2Bb2&UTr}ktYS}NT;{kO7y@X9Z@Cw`az?!4jg)-~t2pP%D1 zZ*k(~m*c-$>|3m5E64k&%3*#^kfLKxVB+o5U+x`V*yp5}&#hR~Q)p-^YrOBAik}GA z`K1Dv&RUAA286gts6{ZYV7hfkkjctHOHx^tS+Qs8V+)z&U9&`l7ilb9C8H2&ye%|b z^mg>@>38y+t8A8Ku%ZHYWl;>!^*79{CA>8`kl6WPucWb zAIWV_Y7|mBIB)&hkH-`A4c4&fv3DF+KOb|kbn&@OYnt9&s@F|3Qe!_Cw|?s!pTA2S z?tXZGW8UoFcJtL+BIGWM^uN0=cRxoX;pV~%w!fwN4|Y{_A6-=S zJ<-H`_6+0hz6XFVdQ&MBb@05PIE A@Bjb+ diff --git a/app/assets/stylesheets/active_admin/_forms.scss b/app/assets/stylesheets/active_admin/_forms.scss index b0b7dc946e8..b9f5de3b170 100644 --- a/app/assets/stylesheets/active_admin/_forms.scss +++ b/app/assets/stylesheets/active_admin/_forms.scss @@ -1,4 +1,3 @@ -//= depend_on_asset "active_admin/datepicker/datepicker-input-icon.png" // -------------------------------------- Active Admin Forms form { /* Reset margins & Padding */ @@ -291,9 +290,7 @@ $filter-field-seperator-width: 12px; $side-by-side-filter-input-width: ($sidebar-inner-content-width / 2) - ($text-input-horizontal-padding * 2) - $filter-field-seperator-width; $side-by-side-filter-select-width: ($sidebar-inner-content-width / 2) - $filter-field-seperator-width; -$date-range-filter-input-right-padding: 27px; -$date-range-filter-input-horizontal-padding: $date-range-filter-input-right-padding + $text-input-horizontal-padding; -$date-range-filter-input-width: ($sidebar-inner-content-width / 2) - $filter-field-seperator-width - $date-range-filter-input-horizontal-padding; +$date-range-filter-input-width: ($sidebar-inner-content-width / 2) - ($filter-field-seperator-width / 2); form.filter_form { .filter_form_field { @@ -327,9 +324,12 @@ form.filter_form { &.filter_date_range { input[type=text] { - background: #fff image-url('active_admin/datepicker/datepicker-input-icon.png') no-repeat 100% 7px; - padding-right: $date-range-filter-input-right-padding; + box-sizing: border-box; width: $date-range-filter-input-width; + + + input { + margin-left: 6px; + } } } } diff --git a/lib/active_admin/inputs/filters/date_range_input.rb b/lib/active_admin/inputs/filters/date_range_input.rb index 6b1612db299..749812750e4 100644 --- a/lib/active_admin/inputs/filters/date_range_input.rb +++ b/lib/active_admin/inputs/filters/date_range_input.rb @@ -7,8 +7,8 @@ class DateRangeInput < ::Formtastic::Inputs::StringInput def to_html input_wrapping do [ label_html, - builder.text_field(gt_input_name, input_html_options(gt_input_name)), - builder.text_field(lt_input_name, input_html_options(lt_input_name)), + builder.text_field(gt_input_name, input_html_options(gt_input_name, gt_input_placeholder)), + builder.text_field(lt_input_name, input_html_options(lt_input_name, lt_input_placeholder)), ].join("\n").html_safe end end @@ -22,7 +22,7 @@ def lt_input_name column && column.type == :date ? "#{method}_lteq" : "#{method}_lteq_datetime" end - def input_html_options(input_name = gt_input_name) + def input_html_options(input_name = gt_input_name, placeholder = gt_input_placeholder) current_value = begin #cast value to date object before rendering input @object.public_send(input_name).to_s.to_date @@ -32,8 +32,17 @@ def input_html_options(input_name = gt_input_name) { size: 12, class: "datepicker", maxlength: 10, + placeholder: placeholder, value: current_value ? current_value.strftime("%Y-%m-%d") : "" } end + + def gt_input_placeholder + I18n.t("active_admin.filters.predicates.starts_with") + end + + def lt_input_placeholder + I18n.t("active_admin.filters.predicates.ends_with") + end end end end From 539b6992c7b7e29d9cce664ee3f2bb39131f2434 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 12:05:11 -0400 Subject: [PATCH 0550/3836] Update placeholders to be "From" and "To" --- config/locales/en.yml | 2 ++ lib/active_admin/inputs/filters/date_range_input.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index f6fbf080d11..f39ab1c9d6d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -34,6 +34,8 @@ en: less_than: "Less than" gteq_datetime: "Greater or equal to" lteq_datetime: "Lesser or equal to" + from: "From" + to: "To" search_status: headline: "Search status:" current_scope: "Scope:" diff --git a/lib/active_admin/inputs/filters/date_range_input.rb b/lib/active_admin/inputs/filters/date_range_input.rb index 749812750e4..85a4c840c3d 100644 --- a/lib/active_admin/inputs/filters/date_range_input.rb +++ b/lib/active_admin/inputs/filters/date_range_input.rb @@ -37,11 +37,11 @@ def input_html_options(input_name = gt_input_name, placeholder = gt_input_placeh end def gt_input_placeholder - I18n.t("active_admin.filters.predicates.starts_with") + I18n.t("active_admin.filters.predicates.from") end def lt_input_placeholder - I18n.t("active_admin.filters.predicates.ends_with") + I18n.t("active_admin.filters.predicates.to") end end end From c7dcc11472db7202ad78b3bda12266846a540e00 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 7 Jun 2017 23:51:53 +0300 Subject: [PATCH 0551/3836] allow to pass additional class for action item block --- lib/active_admin/resource/action_items.rb | 4 ++++ lib/active_admin/views/action_items.rb | 2 +- spec/unit/resource/action_items_spec.rb | 6 +++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/active_admin/resource/action_items.rb b/lib/active_admin/resource/action_items.rb index b2a09094f61..b45c80271b0 100644 --- a/lib/active_admin/resource/action_items.rb +++ b/lib/active_admin/resource/action_items.rb @@ -106,6 +106,10 @@ def initialize(name, options = {}, &block) @block = block normalize_display_options! end + + def html_class + "action_item #{@options[:class]}".rstrip + end end end diff --git a/lib/active_admin/views/action_items.rb b/lib/active_admin/views/action_items.rb index d39cb0add53..1d03236018b 100644 --- a/lib/active_admin/views/action_items.rb +++ b/lib/active_admin/views/action_items.rb @@ -5,7 +5,7 @@ class ActionItems < ActiveAdmin::Component def build(action_items) action_items.each do |action_item| - span class: "action_item" do + span class: action_item.html_class do instance_exec(&action_item.block) end end diff --git a/spec/unit/resource/action_items_spec.rb b/spec/unit/resource/action_items_spec.rb index 5ea839fcb59..da530420c89 100644 --- a/spec/unit/resource/action_items_spec.rb +++ b/spec/unit/resource/action_items_spec.rb @@ -11,7 +11,7 @@ before do resource.clear_action_items! - resource.add_action_item :empty do + resource.add_action_item :empty, class: :test do # Empty ... end end @@ -28,6 +28,10 @@ expect(resource.action_items.first.block).to_not eq nil end + it "should include class from options" do + expect(resource.action_items.first.html_class).to eq("action_item test") + end + end describe "setting an action item to only display on specific controller actions" do From c7ca442e979ab48dd73081b1cc8cec65d2cab173 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 7 Jun 2017 19:55:50 +0300 Subject: [PATCH 0552/3836] allow scope to paginate collection PaginatedCollection works only with paginated scope, so skip apply_pagination if pagination was applied by scope logic to make this work scope can be defined as """ ActiveAdmin.register Post do scope :all scope :random do |posts| posts.random.page(1).per(3) end end """ [fixes #4977] --- CHANGELOG.md | 2 ++ features/index/index_scopes.feature | 7 +++++++ lib/active_admin/resource_controller/data_access.rb | 2 ++ 3 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee37c3a786c..fd283998f74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ ##### Minor +* Allow AA scopes to return paginated collections [#4996][] by [@Fivell][] * Added `scopes_show_count` configuration to setup show_count attribute for scopes globally [#4950][] by [@Fivell][] * Allow custom panel title given with `attributes_table` [#4940][] by [@ajw725][] @@ -151,6 +152,7 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [#4867]: https://github.com/activeadmin/activeadmin/pull/4867 [#4882]: https://github.com/activeadmin/activeadmin/pull/4882 [#4950]: https://github.com/activeadmin/activeadmin/pull/4950 +[#4996]: https://github.com/activeadmin/activeadmin/pull/4996 [@bolshakov]: https://github.com/bolshakov diff --git a/features/index/index_scopes.feature b/features/index/index_scopes.feature index 6f494aba951..7ff5c6e690b 100644 --- a/features/index/index_scopes.feature +++ b/features/index/index_scopes.feature @@ -243,6 +243,9 @@ Feature: Index Scoping scope :published do |posts| posts.where("published_date IS NOT NULL") end + scope :single do |posts| + posts.page(1).per(1) + end index do column :author_id @@ -260,8 +263,12 @@ Feature: Index Scoping """ Then I should see the scope "All" with the count 2 And I should see the scope "Published" with the count 1 + And I should see the scope "Single" with the count 1 And I should see 2 posts in the table + When I follow "Single" + Then I should see 1 posts in the table + When I follow "Published" Then I should see the scope "Published" selected And I should see the scope "All" with the count 2 diff --git a/lib/active_admin/resource_controller/data_access.rb b/lib/active_admin/resource_controller/data_access.rb index 0b8c2ad69ef..24e2e78e318 100644 --- a/lib/active_admin/resource_controller/data_access.rb +++ b/lib/active_admin/resource_controller/data_access.rb @@ -245,6 +245,8 @@ def current_scope end def apply_pagination(chain) + # skip pagination if already was paginated by scope + return chain if chain.respond_to?(:total_pages) page_method_name = Kaminari.config.page_method_name page = params[Kaminari.config.param_name] From 9b3e66349bea7092924334d6111b00e0e781518e Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 23 Mar 2015 23:40:35 -0400 Subject: [PATCH 0553/3836] Replace reset.scss with normalize.css Set text-align: left; as default for th element as normalize leaves browser default of text align center. --- .../stylesheets/active_admin/_base.scss | 4 +- .../active_admin/components/_tables.scss | 5 +- .../stylesheets/active_admin/mixins/_all.scss | 1 - .../active_admin/mixins/_reset.scss | 165 ------- .../stylesheets/active_admin/print.scss | 5 +- .../stylesheets/active_admin/_normalize.css | 447 ++++++++++++++++++ 6 files changed, 455 insertions(+), 172 deletions(-) delete mode 100644 app/assets/stylesheets/active_admin/mixins/_reset.scss create mode 100644 vendor/assets/stylesheets/active_admin/_normalize.css diff --git a/app/assets/stylesheets/active_admin/_base.scss b/app/assets/stylesheets/active_admin/_base.scss index 1090137016b..bfa560f4da9 100644 --- a/app/assets/stylesheets/active_admin/_base.scss +++ b/app/assets/stylesheets/active_admin/_base.scss @@ -1,6 +1,6 @@ /* Active Admin CSS */ -// Reset Away! -@include global-reset; +// Normalize +@import "active_admin/normalize"; // Partials @import "active_admin/typography"; diff --git a/app/assets/stylesheets/active_admin/components/_tables.scss b/app/assets/stylesheets/active_admin/components/_tables.scss index 29bd4337d4f..f2634ed45c9 100644 --- a/app/assets/stylesheets/active_admin/components/_tables.scss +++ b/app/assets/stylesheets/active_admin/components/_tables.scss @@ -5,6 +5,10 @@ table tr { td { vertical-align: top; } + + th { + text-align: left; + } } // --------- Index Tables @@ -18,7 +22,6 @@ table.index_table { th { @include section-header; border-right: none; - text-align: left; padding-left: $cell-horizontal-padding; padding-right: $cell-horizontal-padding; diff --git a/app/assets/stylesheets/active_admin/mixins/_all.scss b/app/assets/stylesheets/active_admin/mixins/_all.scss index 81a65a04076..84e764a3009 100644 --- a/app/assets/stylesheets/active_admin/mixins/_all.scss +++ b/app/assets/stylesheets/active_admin/mixins/_all.scss @@ -1,5 +1,4 @@ @import "active_admin/mixins/variables"; -@import "active_admin/mixins/reset"; @import "active_admin/mixins/gradients"; @import "active_admin/mixins/shadows"; @import "active_admin/mixins/rounded"; diff --git a/app/assets/stylesheets/active_admin/mixins/_reset.scss b/app/assets/stylesheets/active_admin/mixins/_reset.scss deleted file mode 100644 index 7b89b89b278..00000000000 --- a/app/assets/stylesheets/active_admin/mixins/_reset.scss +++ /dev/null @@ -1,165 +0,0 @@ -// FROM The Compass Framework (compass-style.org) -// -// Copyright (c) 2009 Christopher M. Eppstein -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. No attribution is required by -// products that make use of this software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// Except as contained in this notice, the name(s) of the above copyright holders -// shall not be used in advertising or otherwise to promote the sale, use or other -// dealings in this Software without prior written authorization. -// -// Contributors to this project agree to grant all rights to the copyright holder -// of the primary product. Attribution is maintained in the source control history -// of the product. -// -// Based on [Eric Meyer's reset](http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/) -// Global reset rules. -// For more specific resets, use the reset mixins provided below -// -// *Please Note*: tables still need `cellspacing="0"` in the markup. -@mixin global-reset { - html, body, div, span, applet, object, iframe, - h1, h2, h3, h4, h5, h6, p, blockquote, pre, - a, abbr, acronym, address, big, cite, code, - del, dfn, em, font, img, ins, kbd, q, s, samp, - small, strike, strong, sub, sup, tt, var, - dl, dt, dd, ol, ul, li, - fieldset, form, label, legend, - table, caption, tbody, tfoot, thead, tr, th, td { - @include reset-box-model; - @include reset-font; } - body { - @include reset-body; } - ol, ul { - @include reset-list-style; } - table { - @include reset-table; } - caption, th, td { - @include reset-table-cell; } - q, blockquote { - @include reset-quotation; } - a img { - @include reset-image-anchor-border; } } - -// Reset all elements within some selector scope. To reset the selector itself, -// mixin the appropriate reset mixin for that element type as well. This could be -// useful if you want to style a part of your page in a dramatically different way. -// -// *Please Note*: tables still need `cellspacing="0"` in the markup. -@mixin nested-reset { - div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, - pre, a, abbr, acronym, address, code, del, dfn, em, img, - dl, dt, dd, ol, ul, li, fieldset, form, label, legend, caption, tbody, tfoot, thead, tr { - @include reset-box-model; - @include reset-font; } - table { - @include reset-table; } - caption, th, td { - @include reset-table-cell; } - q, blockquote { - @include reset-quotation; } - a img { - @include reset-image-anchor-border; } } - -// Reset the box model measurements. -@mixin reset-box-model { - margin: 0; - padding: 0; - border: 0; - outline: 0; } - -// Reset the font and vertical alignment. -@mixin reset-font { - font: { - weight: inherit; - style: inherit; - size: 100%; - family: inherit; }; - vertical-align: baseline; } - -// Resets the outline when focus. -// For accessibility you need to apply some styling in its place. -@mixin reset-focus { - outline: 0; } - -// Reset a body element. -@mixin reset-body { - line-height: 1; - color: black; - background: white; } - -// Reset the list style of an element. -@mixin reset-list-style { - list-style: none; } - -// Reset a table -@mixin reset-table { - border-collapse: separate; - border-spacing: 0; - vertical-align: middle; } - -// Reset a table cell (`th`, `td`) -@mixin reset-table-cell { - text-align: left; - font-weight: normal; - vertical-align: middle; } - -// Reset a quotation (`q`, `blockquote`) -@mixin reset-quotation { - quotes: "" ""; - &:before, &:after { - content: ""; } } - -// Resets the border. -@mixin reset-image-anchor-border { - border: none; } - -// Unrecognized elements are displayed inline. -// This reset provides a basic reset for html5 elements -// so they are rendered correctly in browsers that don't recognize them -// and reset in browsers that have default styles for them. -@mixin reset-html5 { - article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary { - @include reset-box-model; - display: block; } } - -// Resets the display of inline and block elements to their default display -// according to their tag type. Elements that have a default display that varies across -// versions of html or browser are not handled here, but this covers the 90% use case. -// Usage Example: -// -// // Turn off the display for both of these classes -// .unregistered-only, .registered-only -// display: none -// // Now turn only one of them back on depending on some other context. -// body.registered -// +reset-display(".registered-only") -// body.unregistered -// +reset-display(".unregistered-only") -@mixin reset-display($selector: "", $important: false) { - #{append-selector(elements-of-type("inline"), $selector)} { - @if $important { - display: inline !important; } - @else { - display: inline; } } - #{append-selector(elements-of-type("block"), $selector)} { - @if $important { - display: block !important; } - @else { - display: block; } } } diff --git a/app/assets/stylesheets/active_admin/print.scss b/app/assets/stylesheets/active_admin/print.scss index 338007cfef6..91209eb5419 100644 --- a/app/assets/stylesheets/active_admin/print.scss +++ b/app/assets/stylesheets/active_admin/print.scss @@ -4,9 +4,8 @@ $primary-color: black; $text-color: black; -// Reset -@import "active_admin/mixins/reset"; -@include global-reset; +// Normalize +@import "active_admin/normalize"; // Partials @import "active_admin/typography"; diff --git a/vendor/assets/stylesheets/active_admin/_normalize.css b/vendor/assets/stylesheets/active_admin/_normalize.css new file mode 100644 index 00000000000..fa4e73dd418 --- /dev/null +++ b/vendor/assets/stylesheets/active_admin/_normalize.css @@ -0,0 +1,447 @@ +/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers (opinionated). + */ + +body { + margin: 0; +} + +/** + * Add the correct display in IE 9-. + */ + +article, +aside, +footer, +header, +nav, +section { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + * 1. Add the correct display in IE. + */ + +figcaption, +figure, +main { /* 1 */ + display: block; +} + +/** + * Add the correct margin in IE 8. + */ + +figure { + margin: 1em 40px; +} + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * 1. Remove the gray background on active links in IE 10. + * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. + */ + +a { + background-color: transparent; /* 1 */ + -webkit-text-decoration-skip: objects; /* 2 */ +} + +/** + * 1. Remove the bottom border in Chrome 57- and Firefox 39-. + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Prevent the duplicate application of `bolder` by the next rule in Safari 6. + */ + +b, +strong { + font-weight: inherit; +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font style in Android 4.3-. + */ + +dfn { + font-style: italic; +} + +/** + * Add the correct background and color in IE 9-. + */ + +mark { + background-color: #ff0; + color: #000; +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +audio, +video { + display: inline-block; +} + +/** + * Add the correct display in iOS 4-7. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Remove the border on images inside links in IE 10-. + */ + +img { + border-style: none; +} + +/** + * Hide the overflow in IE. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers (opinionated). + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: sans-serif; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` + * controls in Android 4. + * 2. Correct the inability to style clickable types in iOS and Safari. + */ + +button, +html [type="button"], /* 1 */ +[type="reset"], +[type="submit"] { + -webkit-appearance: button; /* 2 */ +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * 1. Add the correct display in IE 9-. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Remove the default vertical scrollbar in IE. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10-. + * 2. Remove the padding in IE 10-. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in IE 9-. + * 1. Add the correct display in Edge, IE, and Firefox. + */ + +details, /* 1 */ +menu { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Scripting + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +canvas { + display: inline-block; +} + +/** + * Add the correct display in IE. + */ + +template { + display: none; +} + +/* Hidden + ========================================================================== */ + +/** + * Add the correct display in IE 10-. + */ + +[hidden] { + display: none; +} From 241b8b8566d12905b1e918a6978822d781f1bc3a Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 8 Jun 2017 11:26:28 +0300 Subject: [PATCH 0554/3836] added missed links to changelog [skip ci] --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd283998f74..f658eee4331 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ ##### Minor +* Base localization support, better associations handling for active filters sidebar [#4951][] by [@Fivell][] * Allow AA scopes to return paginated collections [#4996][] by [@Fivell][] * Added `scopes_show_count` configuration to setup show_count attribute for scopes globally [#4950][] by [@Fivell][] * Allow custom panel title given with `attributes_table` [#4940][] by [@ajw725][] @@ -151,10 +152,14 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [#4851]: https://github.com/activeadmin/activeadmin/pull/4851 [#4867]: https://github.com/activeadmin/activeadmin/pull/4867 [#4882]: https://github.com/activeadmin/activeadmin/pull/4882 +[#4940]: https://github.com/activeadmin/activeadmin/pull/4940 [#4950]: https://github.com/activeadmin/activeadmin/pull/4950 +[#4951]: https://github.com/activeadmin/activeadmin/pull/4951 +[#4989]: https://github.com/activeadmin/activeadmin/pull/4989 [#4996]: https://github.com/activeadmin/activeadmin/pull/4996 +[@ajw725]: https://github.com/ajw725 [@bolshakov]: https://github.com/bolshakov [@chancancode]: https://github.com/chancancode [@craigmcnamara]: https://github.com/craigmcnamara @@ -163,6 +168,7 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [@drn]: https://github.com/drn [@Fivell]: https://github.com/Fivell [@gonzedge]: https://github.com/gonzedge +[@javierjulio]: https://github.com/javierjulio [@johnnyshields]: https://github.com/johnnyshields [@PChambino]: https://github.com/PChambino [@potatosalad]: https://github.com/potatosalad From 36ca4f90d842daf2c585d89d5d65d271778ee973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 19:39:05 -0300 Subject: [PATCH 0555/3836] Enforce spaces around optional parameter values --- .rubocop.yml | 3 +++ lib/active_admin/csv_builder.rb | 4 ++-- lib/active_admin/dsl.rb | 2 +- lib/active_admin/page_controller.rb | 2 +- lib/active_admin/resource/page_presenters.rb | 2 +- lib/active_admin/resource_dsl.rb | 2 +- lib/active_admin/view_helpers/form_helper.rb | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index d41ae6ee008..2f4821a4bcd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -61,5 +61,8 @@ Layout/TrailingWhitespace: Layout/SpaceAfterComma: Enabled: true +Style/SpaceAroundEqualsInParameterDefault: + Enabled: true + Layout/SpaceInsideParens: Enabled: true diff --git a/lib/active_admin/csv_builder.rb b/lib/active_admin/csv_builder.rb index ba323302a40..55e49a7ebeb 100644 --- a/lib/active_admin/csv_builder.rb +++ b/lib/active_admin/csv_builder.rb @@ -30,12 +30,12 @@ def self.default_for_resource(resource) COLUMN_TRANSITIVE_OPTIONS = [:humanize_name].freeze - def initialize(options={}, &block) + def initialize(options = {}, &block) @resource = options.delete(:resource) @columns, @options, @block = [], options, block end - def column(name, options={}, &block) + def column(name, options = {}, &block) @columns << Column.new(name, @resource, column_transitive_options.merge(options), block) end diff --git a/lib/active_admin/dsl.rb b/lib/active_admin/dsl.rb index d44c232a29c..307c41ff31e 100644 --- a/lib/active_admin/dsl.rb +++ b/lib/active_admin/dsl.rb @@ -137,7 +137,7 @@ def menu(options = {}) # Pass a block returning the name of a menu you want rendered for the request, being # executed in the context of the controller # - def navigation_menu(menu_name=nil, &block) + def navigation_menu(menu_name = nil, &block) config.navigation_menu_name = menu_name || block end diff --git a/lib/active_admin/page_controller.rb b/lib/active_admin/page_controller.rb index db6c9683f93..15b76e72e38 100644 --- a/lib/active_admin/page_controller.rb +++ b/lib/active_admin/page_controller.rb @@ -10,7 +10,7 @@ class PageController < BaseController before_action :authorize_access! - def index(options={}, &block) + def index(options = {}, &block) render "active_admin/page/index" end diff --git a/lib/active_admin/resource/page_presenters.rb b/lib/active_admin/resource/page_presenters.rb index 93d396602ca..e70153b6d5e 100644 --- a/lib/active_admin/resource/page_presenters.rb +++ b/lib/active_admin/resource/page_presenters.rb @@ -33,7 +33,7 @@ def set_page_presenter(action, page_presenter) # @param [Symbol, String] action The action to get the config for # @param [String] type The string specified in the presenters index_name method # @return [PagePresenter, nil] - def get_page_presenter(action, type=nil) + def get_page_presenter(action, type = nil) if action.to_s == "index" && type && page_presenters[:index].kind_of?(Hash) page_presenters[:index][type.to_sym] diff --git a/lib/active_admin/resource_dsl.rb b/lib/active_admin/resource_dsl.rb index 7d21b19ad4e..a057672ba9e 100644 --- a/lib/active_admin/resource_dsl.rb +++ b/lib/active_admin/resource_dsl.rb @@ -105,7 +105,7 @@ def form(options = {}, &block) # column :name # end # - def csv(options={}, &block) + def csv(options = {}, &block) options[:resource] = config config.csv_builder = CSVBuilder.new(options, &block) diff --git a/lib/active_admin/view_helpers/form_helper.rb b/lib/active_admin/view_helpers/form_helper.rb index 225209a7f72..7bbae28ca74 100644 --- a/lib/active_admin/view_helpers/form_helper.rb +++ b/lib/active_admin/view_helpers/form_helper.rb @@ -8,7 +8,7 @@ def active_admin_form_for(resource, options = {}, &block) end.content end - def hidden_field_tags_for(params, options={}) + def hidden_field_tags_for(params, options = {}) fields_for_params(params.to_unsafe_hash, options).map do |kv| k, v = kv.first hidden_field_tag k, v, id: sanitize_to_id("hidden_active_admin_#{k}") From bb1d84caef42f8e965c1e7c28b12955532740eaa Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 22:08:24 -0400 Subject: [PATCH 0556/3836] Allow taggings to be destroyed via nested attrs --- spec/support/rails_template.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index a6c07897014..0d61a330835 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -14,7 +14,7 @@ class Post < ActiveRecord::Base belongs_to :author, class_name: 'User' has_many :taggings accepts_nested_attributes_for :author - accepts_nested_attributes_for :taggings + accepts_nested_attributes_for :taggings, allow_destroy: true ransacker :custom_title_searcher do |parent| parent.table[:title] @@ -43,7 +43,7 @@ class Blog::Post < ActiveRecord::Base belongs_to :author, class_name: 'User' has_many :taggings accepts_nested_attributes_for :author - accepts_nested_attributes_for :taggings + accepts_nested_attributes_for :taggings, allow_destroy: true if defined? ProtectedAttributes attr_accessible :title, :body, :starred, :author, :position, :published_date, :author_id, :custom_category_id, :category From bf9d38b034022932431d062e651c06bf912deff2 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 22:09:22 -0400 Subject: [PATCH 0557/3836] Enable create_another on category/user pages --- spec/support/rails_template_with_data.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 02936691f76..32ed7ff1673 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -6,11 +6,15 @@ inject_into_file 'app/admin/category.rb', <<-RUBY, after: "ActiveAdmin.register Category do\n" + config.create_another = true + permit_params [:name, :description] RUBY inject_into_file 'app/admin/user.rb', <<-RUBY, after: "ActiveAdmin.register User do\n" + config.create_another = true + permit_params [:first_name, :last_name, :username, :age] RUBY From d4c1e0798e9753de47d421131bbb9de69c8ca59d Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 22:11:57 -0400 Subject: [PATCH 0558/3836] Generate tag using auto incremented id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I could not get the uuid backed id to work with a has_many form so I’m updating this to use normal auto incremented ids. This way we can also test sorting too. --- spec/support/rails_template.rb | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 0d61a330835..85dd30cf482 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -101,29 +101,16 @@ class Category < ActiveRecord::Base generate :model, 'store name:string' -# Generate a model with string ids generate :model, 'tag name:string' -gsub_file Dir['db/migrate/*_create_tags.rb'].first, /\:tags do .*/, <<-RUBY.strip_heredoc - :tags, id: false, primary_key: :id do |t| - t.string :id -RUBY create_file 'app/models/tag.rb', <<-RUBY.strip_heredoc, force: true class Tag < ActiveRecord::Base - self.primary_key = :id - before_create :set_id - - private - def set_id - self.id = SecureRandom.uuid - end - if defined? ProtectedAttributes attr_accessible :name end end RUBY -generate :model, 'tagging post_id:integer tag_id:integer' +generate :model, 'tagging post_id:integer tag_id:integer position:integer' create_file 'app/models/tagging.rb', <<-RUBY.strip_heredoc, force: true class Tagging < ActiveRecord::Base belongs_to :post From 373b5bfe09694526ac7b0ff05f7b33a1c62a157f Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 22:26:45 -0400 Subject: [PATCH 0559/3836] Add tag page and enable has many taggings Noticed this model existed but without an admin page. With taggings this makes it a great candidate for testing the has_many form without breaking any tests either. --- spec/support/rails_template_with_data.rb | 76 +++++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 32ed7ff1673..bd088534036 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -1,6 +1,6 @@ apply File.expand_path("../rails_template.rb", __FILE__) -%w{Post User Category}.each do |type| +%w{Post User Category Tag}.each do |type| generate :'active_admin:resource', type end @@ -20,7 +20,7 @@ inject_into_file 'app/admin/post.rb', <<-RUBY, after: "ActiveAdmin.register Post do\n" - permit_params [:custom_category_id, :author_id, :title, :body, :published_date, :position, :starred] + permit_params :custom_category_id, :author_id, :title, :body, :published_date, :position, :starred, taggings_attributes: [ :id, :tag_id, :name, :position, :_destroy ] scope :all, default: true @@ -39,6 +39,78 @@ scope :my_posts do |posts| posts.where(author_id: current_admin_user.id) end + + index do + selectable_column + id_column + column :title + column :published_date + column :author + column :category + column :starred + column :position + column :created_at + column :updated_at + end + + show do |post| + attributes_table do + row :id + row :title + row :body + end + + panel 'Tags' do + table_for(post.taggings.order(:position)) do + column :tag_id do |tagging| + link_to tagging.tag_id, admin_tag_path(tagging.tag) + end + column :tag_name + column :position + column :created_at + column :updated_at + end + end + end + + form do |f| + f.inputs 'Details' do + f.input :title + f.input :body + f.input :starred + f.input :author + f.input :position + f.input :published_date + f.input :author_id + f.input :custom_category_id + f.input :category + end + f.inputs "Tags" do + f.has_many :taggings, sortable: :position do |t| + t.input :tag + t.input :_destroy, as: :boolean + end + end + f.actions + end +RUBY + +inject_into_file 'app/admin/tag.rb', <<-RUBY, after: "ActiveAdmin.register Tag do\n" + + config.create_another = true + + permit_params [:name] + + index do + selectable_column + id_column + column :name + column :created_at + actions dropdown: true do |tag| + item "Preview", admin_tag_path(tag) + end + end + RUBY append_file "db/seeds.rb", "\n\n" + <<-RUBY.strip_heredoc From 8d03ee82be3b7db5043b68b37b1121ec732ef629 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 22:27:02 -0400 Subject: [PATCH 0560/3836] Add custom user show page with posts table --- spec/support/rails_template_with_data.rb | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index bd088534036..fbe51a025c8 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -16,6 +16,34 @@ config.create_another = true permit_params [:first_name, :last_name, :username, :age] + + show do + attributes_table do + row :id + row :first_name + row :last_name + row :username + row :age + row :created_at + row :updated_at + end + + panel 'Posts' do + table_for(user.posts.order(:updated_at).limit(10)) do + column :id do |post| + link_to post.id, admin_post_path(post) + end + column :title + column :published_date + column :category + column :created_at + column :updated_at + end + para do + link_to "View all posts", admin_posts_path('q[author_id_eq]' => user.id) + end + end + end RUBY inject_into_file 'app/admin/post.rb', <<-RUBY, after: "ActiveAdmin.register Post do\n" From 6d0f1f99fe4d7f89fe33d099021dc9f38b2f27a0 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 5 Jun 2017 23:48:50 -0400 Subject: [PATCH 0561/3836] Add a menu to the nav bar --- spec/support/rails_template_with_data.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index fbe51a025c8..842f2773217 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -1,5 +1,15 @@ apply File.expand_path("../rails_template.rb", __FILE__) +inject_into_file 'config/initializers/active_admin.rb', <<-RUBY, after: "ActiveAdmin.setup do |config|\n" + + config.comments_menu = { parent: 'Administrative' } +RUBY + +inject_into_file 'app/admin/admin_user.rb', <<-RUBY, after: "ActiveAdmin.register AdminUser do\n" + + menu parent: "Administrative", priority: 1 +RUBY + %w{Post User Category Tag}.each do |type| generate :'active_admin:resource', type end From eb61364ab4e592fe17e611b9cccec51fe1b0d5dd Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 6 Jun 2017 12:38:20 -0400 Subject: [PATCH 0562/3836] Delegate name so we can use tagging.tag_name --- spec/support/rails_template.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb index 85dd30cf482..27a476104c1 100644 --- a/spec/support/rails_template.rb +++ b/spec/support/rails_template.rb @@ -115,6 +115,8 @@ class Tag < ActiveRecord::Base class Tagging < ActiveRecord::Base belongs_to :post belongs_to :tag + + delegate :name, to: :tag, prefix: true end RUBY From 0083cb17e7262e4f6c3f2ae7560e3486764fe165 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 6 Jun 2017 12:38:50 -0400 Subject: [PATCH 0563/3836] Update to use columns and attributes_table_for --- spec/support/rails_template_with_data.rb | 40 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 842f2773217..51d0a3e9cc2 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -95,18 +95,42 @@ attributes_table do row :id row :title + row :published_date + row :author row :body + row :category + row :starred + row :position + row :created_at + row :updated_at end - panel 'Tags' do - table_for(post.taggings.order(:position)) do - column :tag_id do |tagging| - link_to tagging.tag_id, admin_tag_path(tagging.tag) + columns do + column do + panel 'Tags' do + table_for(post.taggings.order(:position)) do + column :tag_id do |tagging| + link_to tagging.tag_id, admin_tag_path(tagging.tag) + end + column :tag_name + column :position + column :created_at + column :updated_at + end + end + end + column do + panel 'Author' do + attributes_table_for post.author do + row :id do |author| + link_to author.id, admin_user_path(author) + end + row :first_name + row :last_name + row :username + row :age + end end - column :tag_name - column :position - column :created_at - column :updated_at end end end From 17afcf9c352671406ba00be8843a371fd602cb85 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 6 Jun 2017 12:59:33 -0400 Subject: [PATCH 0564/3836] Add a sidebar with attributes_table_for sample To fit something there that made sense, I thought the author data in the sidebar was best so I moved that there and in its previous place I just have it show category which is a has one relationship so also good for an attributes_table_for sample in the panel. Trimmed down the tags table and renamed some columns. --- spec/support/rails_template_with_data.rb | 30 +++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 51d0a3e9cc2..82c8758168d 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -91,6 +91,18 @@ column :updated_at end + sidebar :author, only: :show do + attributes_table_for post.author do + row :id do |author| + link_to author.id, admin_user_path(author) + end + row :first_name + row :last_name + row :username + row :age + end + end + show do |post| attributes_table do row :id @@ -109,26 +121,22 @@ column do panel 'Tags' do table_for(post.taggings.order(:position)) do - column :tag_id do |tagging| + column :id do |tagging| link_to tagging.tag_id, admin_tag_path(tagging.tag) end - column :tag_name + column :tag, &:tag_name column :position - column :created_at column :updated_at end end end column do - panel 'Author' do - attributes_table_for post.author do - row :id do |author| - link_to author.id, admin_user_path(author) + panel 'Category' do + attributes_table_for post.category do + row :id do |category| + link_to category.id, admin_category_path(category) end - row :first_name - row :last_name - row :username - row :age + row :description end end end From 6157705b2c2ba8bd70483fd0b5a38f8bad4b244a Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Fri, 9 Jun 2017 23:07:12 -0400 Subject: [PATCH 0565/3836] Eager load data to avoid n+1 queries and minimize log noise --- spec/support/rails_template_with_data.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 82c8758168d..853541f051a 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -39,7 +39,7 @@ end panel 'Posts' do - table_for(user.posts.order(:updated_at).limit(10)) do + table_for(user.posts.includes(:category).order(:updated_at).limit(10)) do column :id do |post| link_to post.id, admin_post_path(post) end @@ -60,6 +60,8 @@ permit_params :custom_category_id, :author_id, :title, :body, :published_date, :position, :starred, taggings_attributes: [ :id, :tag_id, :name, :position, :_destroy ] + includes :author, :category, :taggings + scope :all, default: true scope :drafts do |posts| From a7ce066c0db59ae8999649f301daad3b33a61f10 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Fri, 9 Jun 2017 23:07:35 -0400 Subject: [PATCH 0566/3836] Add a batch action with custom form for starring posts --- spec/support/rails_template_with_data.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index 853541f051a..f6c1e146ef2 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -80,6 +80,11 @@ posts.where(author_id: current_admin_user.id) end + batch_action :set_starred, form: { starred: :checkbox } do |ids, inputs| + Post.where(id: ids).update_all(starred: inputs['starred'].present?) + redirect_to collection_path, notice: "The posts have been updated." + end + index do selectable_column id_column From d74f32a1fcbe7d758196f530c514f3f02f75d9ee Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 6 Jun 2017 21:36:49 -0400 Subject: [PATCH 0567/3836] Create a custom page and call it Kitchen Sink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is useful since it shows how to create a custom page that isn’t tied to a model but also as its name suggests, a dumping ground for various misc things we want to test out that don’t really fit easily elsewhere. Things like tabs and various basic HTML that we want to see it rendered so we can see how AA styles them. --- spec/support/rails_template_with_data.rb | 66 ++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index f6c1e146ef2..a1a0cb86483 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -10,6 +10,72 @@ menu parent: "Administrative", priority: 1 RUBY +generate :'active_admin:page', 'KitchenSink' + +gsub_file 'app/admin/kitchen_sink.rb', /^ *content.*?end/m, <<-RUBY + + sidebar "Sample Sidebar" do + para "Sidebars can also be used on custom pages." + para do + a "Active Admin", href: "https://github.com/activeadmin/activeadmin" + text_node "is a Ruby on Rails framework for" + em "creating elegant backends" + text_node "for" + strong "website administration." + end + para do + abbr "HTML", title: "HyperText Markup Language" + text_node "is the most basic building block of the Web." + end + end + + content do + columns do + column do + panel "Panel title" do + h1 "This is an h1" + h2 "This is an h2" + h3 "This is an h3" + end + end + column do + table_for User.all do + column :id + column :display_name + column :username + column :age + column :updated_at + end + end + end + + tabs do + tab :first do + ul do + li "List item" + li "Another list item" + li "Last item" + end + ol do + li "First list item" + li "Second list item" + li "Third list item" + end + end + tab :second do + para "A popular quote." + blockquote do + text_node "&ldqou;Be yourself; everyone else is already taken.&rdqou;".html_safe + cite "― Oscar Wilde" + end + end + tab :third do + para "Third tab content." + end + end + end +RUBY + %w{Post User Category Tag}.each do |type| generate :'active_admin:resource', type end From f9410eaa45018cefd29541c34fb34da90398cf55 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 8 Jun 2017 11:33:16 -0400 Subject: [PATCH 0568/3836] Add db to rails_commands list --- tasks/local.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/local.rake b/tasks/local.rake index 521453fb885..bd401e041e8 100644 --- a/tasks/local.rake +++ b/tasks/local.rake @@ -10,7 +10,7 @@ task local: :enforce_version do argv = ARGV[1..-1] # If it's a rails command, or we're using Rails 5, auto add the rails script - rails_commands = %w(generate console server dbconsole g c s runner) + rails_commands = %w(generate console server db dbconsole g c s runner) if Rails::VERSION::MAJOR >= 5 || rails_commands.include?(argv[0]) argv.unshift('rails') From 77b9ad6f3675ccd7054b185ad2b6bbc98c15de25 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 8 Jun 2017 17:32:08 -0400 Subject: [PATCH 0569/3836] Use grid as index page type --- spec/support/rails_template_with_data.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index a1a0cb86483..cec4056a5fa 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -93,6 +93,19 @@ permit_params [:first_name, :last_name, :username, :age] + index as: :grid do |user| + div for: user do + resource_selection_cell user + h2 link_to(user.display_name, admin_user_path(user)), style: 'margin-bottom: 0' + para do + strong user.username, style: 'text-transform: uppercase; font-size: 10px;' + br + em user.age + text_node 'years old' + end + end + end + show do attributes_table do row :id From 7aae8c9489f5b7d4308c63799ed3e9caca6f920f Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Fri, 9 Jun 2017 12:10:55 -0400 Subject: [PATCH 0570/3836] Add custom action item and member action Simple action here to toggle the starred attribute on post. --- spec/support/rails_template_with_data.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index cec4056a5fa..bca643302cf 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -189,6 +189,15 @@ end end + member_action :toggle_starred, method: :put do + resource.update(starred: !resource.starred) + redirect_to resource_path, notice: "Post updated." + end + + action_item :toggle_starred, only: :show do + link_to 'Toggle Starred', toggle_starred_admin_post_path(post), method: :put + end + show do |post| attributes_table do row :id From ccfa5e903fd1b2282f3e293314626bfaedd87bd5 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Fri, 9 Jun 2017 12:28:01 -0400 Subject: [PATCH 0571/3836] Update post form with more variation There are a lot of things we style in the form so this helps enable more of that for testing. --- spec/support/rails_template_with_data.rb | 31 +++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb index bca643302cf..ac617c999b3 100644 --- a/spec/support/rails_template_with_data.rb +++ b/spec/support/rails_template_with_data.rb @@ -135,7 +135,7 @@ end RUBY -inject_into_file 'app/admin/post.rb', <<-RUBY, after: "ActiveAdmin.register Post do\n" +inject_into_file 'app/admin/post.rb', <<-'RUBY', after: "ActiveAdmin.register Post do\n" permit_params :custom_category_id, :author_id, :title, :body, :published_date, :position, :starred, taggings_attributes: [ :id, :tag_id, :name, :position, :_destroy ] @@ -239,16 +239,24 @@ end form do |f| - f.inputs 'Details' do - f.input :title - f.input :body - f.input :starred - f.input :author - f.input :position - f.input :published_date - f.input :author_id - f.input :custom_category_id - f.input :category + columns do + column do + f.inputs 'Details' do + f.input :title + f.input :author + f.input :published_date, + hint: f.object.persisted? && "Created at #{f.object.created_at}" + f.input :custom_category_id + f.input :category + f.input :position + f.input :starred + end + end + column do + f.inputs 'Content' do + f.input :body + end + end end f.inputs "Tags" do f.has_many :taggings, sortable: :position do |t| @@ -256,6 +264,7 @@ t.input :_destroy, as: :boolean end end + para "Press cancel to return to the list without saving." f.actions end RUBY From d9b88c1276b06a881bfad5be61c7751435218c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 3 Jun 2017 13:44:26 -0300 Subject: [PATCH 0572/3836] Remove mention to Rails 4 --- docs/documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/documentation.md b/docs/documentation.md index 876f303705e..37f9c2906a3 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -13,7 +13,7 @@ little effort. ### Getting Started -Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails 4 application. To +Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails application. To install, simply add the following to your Gemfile: ```ruby From ad3af5ea12058e9924b19f18bca1d7cdf0449820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 12:30:31 -0300 Subject: [PATCH 0573/3836] Add mdl for markdown linting --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 6e7b79681d7..7b71863e2f7 100644 --- a/Gemfile +++ b/Gemfile @@ -20,6 +20,7 @@ gem 'pry' # Easily debug from your console with `binding.pry` # Code style gem 'rubocop', '0.49.1' +gem 'mdl', '0.4.0' # Translations gem 'i18n-tasks' From 987c2f13a18314fd34cd77ce425f0495d39d796d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 12:35:24 -0300 Subject: [PATCH 0574/3836] Fenced code blocks surrounded by blank lines --- docs/0-installation.md | 3 +++ docs/1-general-configuration.md | 4 ++++ docs/10-custom-pages.md | 1 + docs/2-resource-customization.md | 1 + docs/3-index-pages.md | 1 + docs/4-csv-format.md | 1 + docs/5-forms.md | 2 +- 7 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/0-installation.md b/docs/0-installation.md index e3b7181608c..32ea53a56a9 100644 --- a/docs/0-installation.md +++ b/docs/0-installation.md @@ -23,16 +23,19 @@ that can be injected into your existing Ruby on Rails application. After installing the gem, you need to run the generator. Here are your options: - If you don't want to use Devise, run it with `--skip-users`: + ```sh rails g active_admin:install --skip-users ``` - If you want to use an existing user class, provide it as an argument: + ```sh rails g active_admin:install User ``` - Otherwise, with no arguments we will create an `AdminUser` class to use with Devise: + ```sh rails g active_admin:install ``` diff --git a/docs/1-general-configuration.md b/docs/1-general-configuration.md index e512eed3f9b..a6a0a53c1d9 100644 --- a/docs/1-general-configuration.md +++ b/docs/1-general-configuration.md @@ -140,16 +140,19 @@ config.comments_registration_name = 'AdminComment' You can change the order for the comments and you can change the column to be used for ordering: + ```ruby config.comments_order = 'created_at ASC' ``` You can disable the menu item for the comments index page: + ```ruby config.comments_menu = false ``` You can customize the comment menu: + ```ruby config.comments_menu = { parent: 'Admin', priority: 1 } ``` @@ -177,6 +180,7 @@ end By default, Active Admin displays a "Powered by ActiveAdmin" message on every page. You can override this message and show domain-specific messaging: + ```ruby config.footer = "MyApp Revision v1.3" ``` diff --git a/docs/10-custom-pages.md b/docs/10-custom-pages.md index fd9caa10fe1..d6829addc13 100644 --- a/docs/10-custom-pages.md +++ b/docs/10-custom-pages.md @@ -128,4 +128,5 @@ page_action :add_event, method: [:get, :post] do # ... end ``` + See also the [Custom Actions](8-custom-actions.md#http-verbs) example. \ No newline at end of file diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index 8f75ff042cb..050e6ba0a04 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -194,6 +194,7 @@ end ### Conditionally Showing / Hiding Menu Items Menu items can be shown or hidden at runtime using the `:if` option. + ```ruby ActiveAdmin.register Post do menu if: proc{ current_user.can_edit_posts? } diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index 9e4d79795e2..bf52dddb2ac 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -113,6 +113,7 @@ Also, if you don't need the select with the options 'contains', 'equals', 'start just add the option to the filter name with an underscore. For example: + ```ruby filter :name_equals # or diff --git a/docs/4-csv-format.md b/docs/4-csv-format.md index 474b26a5338..d6e12622260 100644 --- a/docs/4-csv-format.md +++ b/docs/4-csv-format.md @@ -43,6 +43,7 @@ config.csv_options = { force_quotes: true } ``` You can customize the filename by overriding `csv_filename` in the controller block. + ```ruby ActiveAdmin.register User do controller do diff --git a/docs/5-forms.md b/docs/5-forms.md index 6587105b695..2c2ec867076 100644 --- a/docs/5-forms.md +++ b/docs/5-forms.md @@ -178,7 +178,7 @@ You can arrange content in tabs as shown below: In order to simplify creating multiple resources you may enable ActiveAdmin to show nice "Create Another" checkbox alongside of Create Model button. It may be enabled for the whole application: - + ```ruby ActiveAdmin.setup do |config| config.create_another = true From b3eab637e6a7d9bfa9fa088d3d30059d0c6a53c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 12:38:31 -0300 Subject: [PATCH 0575/3836] No multiple consecutive blank lines --- docs/13-authorization-adapter.md | 1 - docs/14-gotchas.md | 1 - docs/3-index-pages/index-as-table.md | 1 - docs/4-csv-format.md | 1 - 4 files changed, 4 deletions(-) diff --git a/docs/13-authorization-adapter.md b/docs/13-authorization-adapter.md index 0ea34ad87f1..c007e9c2acb 100644 --- a/docs/13-authorization-adapter.md +++ b/docs/13-authorization-adapter.md @@ -127,7 +127,6 @@ By default Active Admin simplifies the controller actions into 4 actions: Each of these actions is available as a constant. Eg: `:read` is available as `ActiveAdmin::Authorization::READ`. - ## Checking for Authorization in Controllers and Views Active Admin provides a helper method to check if the current user is diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 9b444c90931..f2fe579abac 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -113,7 +113,6 @@ module SampleApp end ``` - ## Authentication & Application Controller The `ActiveAdmin::BaseController` inherits from the `ApplicationController`. Any authentication method(s) specified in the `ApplicationController` callbacks will be called instead of the authentication method in the active admin config file. For example, if the ApplicationController has a callback `before_action :custom_authentication_method` and the config file's authentication method is `config.authentication_method = :authenticate_active_admin_user`, then `custom_authentication_method` will be called instead of `authenticate_active_admin_user`. diff --git a/docs/3-index-pages/index-as-table.md b/docs/3-index-pages/index-as-table.md index 61d61b453b7..2937279270a 100644 --- a/docs/3-index-pages/index-as-table.md +++ b/docs/3-index-pages/index-as-table.md @@ -208,7 +208,6 @@ index do end ``` - ## Showing and Hiding Columns The entire index block is rendered within the context of the view, so you can diff --git a/docs/4-csv-format.md b/docs/4-csv-format.md index d6e12622260..cf510f96db5 100644 --- a/docs/4-csv-format.md +++ b/docs/4-csv-format.md @@ -54,7 +54,6 @@ ActiveAdmin.register User do end ``` - ## Streaming By default Active Admin streams the CSV response to your browser as it's generated. From a8219c3b35ddd1470a940b9e238c914e7fc7600e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 12:42:27 -0300 Subject: [PATCH 0576/3836] First header should be a top level header --- docs/0-installation.md | 1 + docs/1-general-configuration.md | 1 + docs/10-custom-pages.md | 1 + docs/11-decorators.md | 1 + docs/12-arbre-components.md | 1 + docs/13-authorization-adapter.md | 1 + docs/14-gotchas.md | 3 ++- docs/2-resource-customization.md | 1 + docs/3-index-pages.md | 1 + docs/3-index-pages/custom-index.md | 1 + docs/4-csv-format.md | 1 + docs/5-forms.md | 1 + docs/8-custom-actions.md | 1 + docs/9-batch-actions.md | 1 + docs/documentation.md | 4 ++-- 15 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/0-installation.md b/docs/0-installation.md index 32ea53a56a9..734c7cf1dba 100644 --- a/docs/0-installation.md +++ b/docs/0-installation.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/0-installation.html --- + # Installation Active Admin is a Ruby Gem. diff --git a/docs/1-general-configuration.md b/docs/1-general-configuration.md index a6a0a53c1d9..b08fb217d38 100644 --- a/docs/1-general-configuration.md +++ b/docs/1-general-configuration.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/1-general-configuration.html --- + # General Configuration You can configure Active Admin settings in `config/initializers/active_admin.rb`. diff --git a/docs/10-custom-pages.md b/docs/10-custom-pages.md index d6829addc13..ccbc820572c 100644 --- a/docs/10-custom-pages.md +++ b/docs/10-custom-pages.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/10-custom-pages.html --- + # Custom Pages If you have data you want on a standalone page that isn't tied to a resource, diff --git a/docs/11-decorators.md b/docs/11-decorators.md index 64ec437166e..84263f786f0 100644 --- a/docs/11-decorators.md +++ b/docs/11-decorators.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/11-decorators.html --- + # Decorators Active Admin allows you to use the decorator pattern to provide view-specific diff --git a/docs/12-arbre-components.md b/docs/12-arbre-components.md index 84dfe8dfefd..835228e48d8 100644 --- a/docs/12-arbre-components.md +++ b/docs/12-arbre-components.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/12-arbre-components.html --- + # Arbre Components Arbre allows the creation of shareable and extendable HTML components and is diff --git a/docs/13-authorization-adapter.md b/docs/13-authorization-adapter.md index c007e9c2acb..d3811f83199 100644 --- a/docs/13-authorization-adapter.md +++ b/docs/13-authorization-adapter.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/13-authorization-adapter.html --- + # Authorization Adapter Active Admin offers the ability to define and use your own authorization diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index f2fe579abac..1055900d98f 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -1,7 +1,8 @@ --- redirect_from: /docs/14-gotchas.html --- -#Gotchas + +# Gotchas ## Security diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index 050e6ba0a04..c3cba5b8a8a 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/2-resource-customization.html --- + # Working with Resources Every Active Admin resource corresponds to a Rails model. So before creating a diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index bf52dddb2ac..a272764a118 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/3-index-pages.html --- + # Customizing the Index Page Filtering and listing resources is one of the most important tasks for diff --git a/docs/3-index-pages/custom-index.md b/docs/3-index-pages/custom-index.md index e9ec8c3af9b..9f05570abd9 100644 --- a/docs/3-index-pages/custom-index.md +++ b/docs/3-index-pages/custom-index.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/3-index-pages/custom-index.html --- + # Custom Index If the supplied Active Admin index components are insufficient for your project diff --git a/docs/4-csv-format.md b/docs/4-csv-format.md index cf510f96db5..0dd877e9b92 100644 --- a/docs/4-csv-format.md +++ b/docs/4-csv-format.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/4-csv-format.html --- + # Customizing the CSV format Active Admin provides CSV file downloads on the index screen for each Resource. diff --git a/docs/5-forms.md b/docs/5-forms.md index 2c2ec867076..719abf6a237 100644 --- a/docs/5-forms.md +++ b/docs/5-forms.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/5-forms.html --- + # Forms Active Admin gives you complete control over the output of the form by creating diff --git a/docs/8-custom-actions.md b/docs/8-custom-actions.md index fb4b0b6b461..7a3aa33d950 100644 --- a/docs/8-custom-actions.md +++ b/docs/8-custom-actions.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/8-custom-actions.html --- + # Custom Controller Actions Active Admin allows you to override and modify the underlying controller which diff --git a/docs/9-batch-actions.md b/docs/9-batch-actions.md index 8b8e9640f39..721a64cd1b2 100644 --- a/docs/9-batch-actions.md +++ b/docs/9-batch-actions.md @@ -1,6 +1,7 @@ --- redirect_from: /docs/9-batch-actions.html --- + # Batch Actions By default, the index page provides you a "Batch Action" to quickly delete records, diff --git a/docs/documentation.md b/docs/documentation.md index 37f9c2906a3..cf94a25e6d3 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -11,7 +11,7 @@ redirect_from: /docs/documentation.html Active Admin is a framework for creating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort. -### Getting Started +# Getting Started Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails application. To install, simply add the following to your Gemfile: @@ -52,7 +52,7 @@ $> rails generate active_admin:resource This creates a file at app/admin/my_model_names.rb for configuring the resource. Refresh your web browser to see the interface. -### Next Steps +# Next Steps Now that you have a working Active Admin installation, learn how to customize it: From 5145dc7c21c9176697edb7278f3ed04db7c1dceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:08:42 -0300 Subject: [PATCH 0577/3836] Fix bad character in heading --- docs/10-custom-pages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/10-custom-pages.md b/docs/10-custom-pages.md index ccbc820572c..a20af5dd3a1 100644 --- a/docs/10-custom-pages.md +++ b/docs/10-custom-pages.md @@ -53,7 +53,7 @@ end See the [Menu](2-resource-customization.md#customize-the-menu) documentation. -## Customize the breadcrumbs +## Customize the breadcrumbs ```ruby ActiveAdmin.register_page "Calendar" do From b23c0cecacaa1a24b9a058a5dc5fb780f5dd844d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:11:18 -0300 Subject: [PATCH 0578/3836] Remove trailing whitespace --- docs/12-arbre-components.md | 2 +- docs/14-gotchas.md | 18 +++++++++--------- docs/3-index-pages/index-as-table.md | 2 +- docs/9-batch-actions.md | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/12-arbre-components.md b/docs/12-arbre-components.md index 835228e48d8..46e49a31f73 100644 --- a/docs/12-arbre-components.md +++ b/docs/12-arbre-components.md @@ -22,7 +22,7 @@ ActiveAdmin.register Post do row :id row 'Tags' do post.tags.each do |tag| - a tag, href: admin_post_path(q: {tagged_with_contains: tag}) + a tag, href: admin_post_path(q: {tagged_with_contains: tag}) text_node " ".html_safe end end diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 1055900d98f..14355e084dc 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -12,13 +12,13 @@ If your CSV export includes untrusted data provided by your users, it's possible ## Session Commits & Asset Pipeline -When configuring the asset pipeline ensure that the asset prefix -(`config.assets.prefix`) is not the same as the namespace of ActiveAdmin -(default namespace is `/admin`). If they are the same Sprockets will prevent the -session from being committed. Flash messages won't work and you will be unable to +When configuring the asset pipeline ensure that the asset prefix +(`config.assets.prefix`) is not the same as the namespace of ActiveAdmin +(default namespace is `/admin`). If they are the same Sprockets will prevent the +session from being committed. Flash messages won't work and you will be unable to use the session for storing anything. -For more information see the following post: +For more information see the following post: [http://www.intridea.com/blog/2013/3/20/rails-assets-prefix-may-disable-your-session](http://www.intridea.com/blog/2013/3/20/rails-assets-prefix-may-disable-your-session) ## Helpers @@ -33,7 +33,7 @@ the only way is to restart your server each time you change a helper. ### Helper maybe not included by default -If you use `config.action_controller.include_all_helpers = false` in your application config, +If you use `config.action_controller.include_all_helpers = false` in your application config, you need to include it by hand. #### Solutions @@ -71,15 +71,15 @@ In order to avoid the override of your application style with the Active Admin o ### With gems that provides a `search` class method on a model -If a gem defines a `search` class method on a model, this can result in conflicts +If a gem defines a `search` class method on a model, this can result in conflicts with the same method provided by `ransack` (a dependency of ActiveAdmin). -Each of this conflicts need to solved is a different way. Some solutions are +Each of this conflicts need to solved is a different way. Some solutions are listed below. #### `tire`, `retire` and `elasticsearch-rails` -This conflict can be solved, by using explicitly the `search` method of `tire`, +This conflict can be solved, by using explicitly the `search` method of `tire`, `retire` or `elasticsearch-rails`: ##### For `tire` and `retire` diff --git a/docs/3-index-pages/index-as-table.md b/docs/3-index-pages/index-as-table.md index 2937279270a..c2cc4507f14 100644 --- a/docs/3-index-pages/index-as-table.md +++ b/docs/3-index-pages/index-as-table.md @@ -167,7 +167,7 @@ index do end ``` -## Custom sorting +## Custom sorting It is also possible to use database specific expressions and options for sorting by column diff --git a/docs/9-batch-actions.md b/docs/9-batch-actions.md index 721a64cd1b2..3e09f817060 100644 --- a/docs/9-batch-actions.md +++ b/docs/9-batch-actions.md @@ -52,7 +52,7 @@ end # app/admin/post.rb ActiveAdmin.register Post do - + # Resource level: config.batch_actions = false end From 0dc4ef8b116edc49486bfee38f067a9092176c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:12:01 -0300 Subject: [PATCH 0579/3836] Unindented bulleted lists --- docs/13-authorization-adapter.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/13-authorization-adapter.md b/docs/13-authorization-adapter.md index d3811f83199..ae65eae09d7 100644 --- a/docs/13-authorization-adapter.md +++ b/docs/13-authorization-adapter.md @@ -117,13 +117,13 @@ end By default Active Admin simplifies the controller actions into 4 actions: - * `:read` - This controls if the user can view the menu item as well as the - index and show screens. - * `:create` - This controls if the user can view the new screen and submit - the form to the create action. - * `:update` - This controls if the user can view the edit screen and submit - the form to the update action. - * `:destroy` - This controls if the user can delete a resource. +* `:read` - This controls if the user can view the menu item as well as the + index and show screens. +* `:create` - This controls if the user can view the new screen and submit + the form to the create action. +* `:update` - This controls if the user can view the edit screen and submit + the form to the update action. +* `:destroy` - This controls if the user can delete a resource. Each of these actions is available as a constant. Eg: `:read` is available as `ActiveAdmin::Authorization::READ`. From 0764a66377d2df748110e3ca5def279a093cc636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:13:38 -0300 Subject: [PATCH 0580/3836] Consistent style for unordered lists --- docs/0-installation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/0-installation.md b/docs/0-installation.md index 734c7cf1dba..49b0cb2ad7a 100644 --- a/docs/0-installation.md +++ b/docs/0-installation.md @@ -23,19 +23,19 @@ that can be injected into your existing Ruby on Rails application. After installing the gem, you need to run the generator. Here are your options: -- If you don't want to use Devise, run it with `--skip-users`: +* If you don't want to use Devise, run it with `--skip-users`: ```sh rails g active_admin:install --skip-users ``` -- If you want to use an existing user class, provide it as an argument: +* If you want to use an existing user class, provide it as an argument: ```sh rails g active_admin:install User ``` -- Otherwise, with no arguments we will create an `AdminUser` class to use with Devise: +* Otherwise, with no arguments we will create an `AdminUser` class to use with Devise: ```sh rails g active_admin:install From 635908bb4d2320b611cfe03f6074b78fa27af416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:14:24 -0300 Subject: [PATCH 0581/3836] No bare URL unless in code blocks --- docs/documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/documentation.md b/docs/documentation.md index cf94a25e6d3..877855448f0 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -36,7 +36,7 @@ $> rake db:migrate $> rails server ``` -Visit http://localhost:3000/admin and log in using: +Visit `http://localhost:3000/admin` and log in using: * User: admin@example.com * Password: password From 5596fc43d8b03daf4f6ddd580315c281363d9043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:16:37 -0300 Subject: [PATCH 0582/3836] Don't use inline HTML --- docs/documentation.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/docs/documentation.md b/docs/documentation.md index 877855448f0..5e3a91e214c 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -1,12 +1,6 @@ --- redirect_from: /docs/documentation.html --- -

      - - Documentation : - - Active Admin Documentation -

      Active Admin is a framework for creating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very little effort. @@ -27,7 +21,7 @@ After updating your bundle, run the installer rails generate active_admin:install ``` -The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at app/admin to put all your admin configurations. +The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at `app/admin` to put all your admin configurations. Migrate your db and start the server: @@ -38,8 +32,8 @@ $> rails server Visit `http://localhost:3000/admin` and log in using: -* User: admin@example.com -* Password: password +* __User__: admin@example.com +* __Password__: password Voila! You’re on your brand new Active Admin dashboard. @@ -50,13 +44,13 @@ $> rails generate active_admin:resource [MyModelName] ``` -This creates a file at app/admin/my_model_names.rb for configuring the resource. Refresh your web browser to see the interface. +This creates a file at `app/admin/my_model_names.rb` for configuring the resource. Refresh your web browser to see the interface. # Next Steps Now that you have a working Active Admin installation, learn how to customize it: -* Customize the Index Page -* Customize the New and Edit Form -* Customize the Show Page -* Customize the Resource in General +* [Customize the Index Page](3-index-pages.md) +* [Customize the New and Edit Form](5-forms.md) +* [Customize the Show Page](6-show-pages.md) +* [Customize the Resource in General](2-resource-customization.md) From a8713d1a9f155a08e203e9450700690d14f293b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:17:40 -0300 Subject: [PATCH 0583/3836] Increment one header level at a time --- docs/12-arbre-components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/12-arbre-components.md b/docs/12-arbre-components.md index 46e49a31f73..b1b5a195c3a 100644 --- a/docs/12-arbre-components.md +++ b/docs/12-arbre-components.md @@ -58,7 +58,7 @@ The Columns component allows you draw content into scalable columns. All you need to do is define the number of columns and the component will take care of the rest. -#### Simple Columns +### Simple Columns To create simple columns, use the `columns` method. Within the block, call the #column method to create a new column. From 7e5f917233f40cfd7874b600964af5db3f193e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:18:21 -0300 Subject: [PATCH 0584/3836] Surround lists by blank lines --- docs/14-gotchas.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 14355e084dc..653df8b39da 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -64,6 +64,7 @@ end ## CSS In order to avoid the override of your application style with the Active Admin one, you can do one of these things: + * You can properly move the generated file `active_admin.scss` from `app/assets/stylesheets` to `vendor/assets/stylesheets`. * You can remove all `require_tree` commands from your root level css files, where the `active_admin.scss` is in the tree. From 7df70284699aa40dadb58356c34c562b4dcb9c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:31:02 -0300 Subject: [PATCH 0585/3836] Wrap lines to 80 characters for readability --- docs/0-installation.md | 7 ++-- docs/1-general-configuration.md | 8 ++-- docs/10-custom-pages.md | 11 ++++-- docs/13-authorization-adapter.md | 45 ++++++++++++++------- docs/14-gotchas.md | 38 +++++++++++++----- docs/2-resource-customization.md | 47 ++++++++++++++-------- docs/3-index-pages.md | 29 ++++++++------ docs/3-index-pages/index-as-table.md | 35 ++++++++++------- docs/5-forms.md | 59 +++++++++++++++++++--------- docs/6-show-pages.md | 3 +- docs/7-sidebars.md | 3 +- docs/8-custom-actions.md | 4 +- docs/9-batch-actions.md | 3 +- docs/documentation.md | 16 +++++--- 14 files changed, 204 insertions(+), 104 deletions(-) diff --git a/docs/0-installation.md b/docs/0-installation.md index 49b0cb2ad7a..88aa27263e2 100644 --- a/docs/0-installation.md +++ b/docs/0-installation.md @@ -71,7 +71,8 @@ To register an existing model with Active Admin: rails generate active_admin:resource MyModel ``` -This creates a file at `app/admin/my_model.rb` to set up the UI; refresh your browser to see it. +This creates a file at `app/admin/my_model.rb` to set up the UI; refresh your +browser to see it. # Upgrading @@ -102,8 +103,8 @@ Kaminari.configure do |config| end ``` -If you are also using [Draper](https://github.com/drapergem/draper), you may want to -make sure `per_page_kaminari` is delegated correctly: +If you are also using [Draper](https://github.com/drapergem/draper), you may +want to make sure `per_page_kaminari` is delegated correctly: ```ruby Draper::CollectionDecorator.send :delegate, :per_page_kaminari diff --git a/docs/1-general-configuration.md b/docs/1-general-configuration.md index b08fb217d38..1279949d59c 100644 --- a/docs/1-general-configuration.md +++ b/docs/1-general-configuration.md @@ -46,10 +46,12 @@ config.site_title_image = ->(context) { context.current_user.company.logo_url } ## Internationalization (I18n) -To translate Active Admin to a new language or customize an existing translation, you can copy +To translate Active Admin to a new language or customize an existing +translation, you can copy [config/locales/en.yml](https://github.com/activeadmin/activeadmin/blob/master/config/locales/en.yml) -to your application's `config/locales` folder and update it. We welcome new/updated translations, -so feel free to [contribute](https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md)! +to your application's `config/locales` folder and update it. We welcome +new/updated translations, so feel free to +[contribute](https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md)! To translate third party gems like devise, use for example devise-i18n. ## Localize Format For Dates and Times diff --git a/docs/10-custom-pages.md b/docs/10-custom-pages.md index a20af5dd3a1..40a01eba342 100644 --- a/docs/10-custom-pages.md +++ b/docs/10-custom-pages.md @@ -86,7 +86,8 @@ ActiveAdmin.register_page "Status" do end ``` -See also the [Belongs To](2-resource-customization.md#belongs-to) documentation and examples. +See also the [Belongs To](2-resource-customization.md#belongs-to) documentation +and examples. ## Add a Sidebar @@ -105,7 +106,8 @@ end ## Add a Page Action -Page actions are custom controller actions (which mirror the resource DSL for the same feature). +Page actions are custom controller actions (which mirror the resource DSL for +the same feature). ```ruby page_action :add_event, method: :post do @@ -120,7 +122,8 @@ end This defines the route `/admin/calendar/add_event` which can handle HTTP POST requests. -Clicking on the action item will reload page and display the message "Your event was added" +Clicking on the action item will reload page and display the message "Your event +was added" Page actions can handle multiple HTTP verbs. @@ -130,4 +133,4 @@ page_action :add_event, method: [:get, :post] do end ``` -See also the [Custom Actions](8-custom-actions.md#http-verbs) example. \ No newline at end of file +See also the [Custom Actions](8-custom-actions.md#http-verbs) example. diff --git a/docs/13-authorization-adapter.md b/docs/13-authorization-adapter.md index ae65eae09d7..bc5b1caec46 100644 --- a/docs/13-authorization-adapter.md +++ b/docs/13-authorization-adapter.md @@ -41,7 +41,8 @@ application's `config/initializers/active_admin.rb` and add/modify the line: config.authorization_adapter = "OnlyAuthorsAuthorization" ``` -Authorization adapters can be configured per ActiveAdmin namespace as well, for example: +Authorization adapters can be configured per ActiveAdmin namespace as well, for +example: ```ruby ActiveAdmin.setup do |config| @@ -74,9 +75,9 @@ end ## Scoping Collections in Authorization Adapters -`ActiveAdmin::AuthorizationAdapter` also provides a hook method (`#scope_collection`) -for the adapter to scope the resource's collection. For example, you may want to -centralize the scoping: +`ActiveAdmin::AuthorizationAdapter` also provides a hook method +(`#scope_collection`) for the adapter to scope the resource's collection. For +example, you may want to centralize the scoping: ```ruby class OnlyMyAccount < ActiveAdmin::AuthorizationAdapter @@ -105,7 +106,9 @@ class OnlyDashboard < ActiveAdmin::AuthorizationAdapter def authorized?(action, subject = nil) case subject when ActiveAdmin::Page - action == :read && subject.name == "Dashboard" && subject.namespace.name == :admin + action == :read && + subject.name == "Dashboard" && + subject.namespace.name == :admin else false end @@ -187,18 +190,19 @@ initializer: config.authorization_adapter = ActiveAdmin::CanCanAdapter ``` -You can also specify a method to be called on unauthorized access. This is necessary -in order to prevent a redirect loop that can happen if a user tries to access a page -they don't have permissions for (see [#2081](https://github.com/activeadmin/activeadmin/issues/2081)). +You can also specify a method to be called on unauthorized access. This is +necessary in order to prevent a redirect loop that can happen if a user tries to +access a page they don't have permissions for (see +[#2081](https://github.com/activeadmin/activeadmin/issues/2081)). ```ruby config.on_unauthorized_access = :access_denied ``` -The method `access_denied` would be defined in `application_controller.rb`. Here is one -example that redirects the user from the page they don't have permission to -access to a resource they have permission to access (organizations in this case), and -also displays the error message in the browser: +The method `access_denied` would be defined in `application_controller.rb`. Here +is one example that redirects the user from the page they don't have permission +to access to a resource they have permission to access (organizations in this +case), and also displays the error message in the browser: ```ruby class ApplicationController < ActionController::Base @@ -235,11 +239,14 @@ class Ability end ``` -To view more details about the API's, visit project pages of [CanCan](https://github.com/ryanb/cancan) and [CanCanCan](https://github.com/CanCanCommunity/cancancan). +To view more details about the API's, visit project pages of +[CanCan](https://github.com/ryanb/cancan) and +[CanCanCan](https://github.com/CanCanCommunity/cancancan). ## Using the Pundit Adapter -Active Admin provides an adapter out of the box also for [Pundit](https://github.com/elabs/pundit). +Active Admin provides an adapter out of the box also for +[Pundit](https://github.com/elabs/pundit). To use the Pundit adapter, simply update the configuration in the Active Admin initializer: @@ -248,4 +255,12 @@ initializer: config.authorization_adapter = ActiveAdmin::PunditAdapter ``` -You can simply use Pundit the way that you would expect and Active Admin will use it for authorization. Check Pundit's documentation to [set up Pundit in your application](https://github.com/elabs/pundit#installation). If you want to use batch actions just ensure that `destroy_all?` method is defined in your policy class. You can use this [template policy](https://github.com/activeadmin/activeadmin/blob/master/spec/support/templates/policies/application_policy.rb) in your application instead of default one generated by Pundit's `rails g pundit:install` command. +You can simply use Pundit the way that you would expect and Active Admin will +use it for authorization. Check Pundit's documentation to [set up Pundit in your +application](https://github.com/elabs/pundit#installation). If you want to use +batch actions just ensure that `destroy_all?` method is defined in your policy +class. You can use this [template +policy](https://github.com/activeadmin/activeadmin/blob/master/spec/support/templates/policies/application_policy.rb) +in your application instead of default one generated by Pundit's `rails g +pundit:install` command. + diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 653df8b39da..68335027075 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -8,7 +8,11 @@ redirect_from: /docs/14-gotchas.html ### Spreadsheet applications vulnerable to unescaped CSV data -If your CSV export includes untrusted data provided by your users, it's possible that they could include an executable formula that could call arbitrary commands on your computer. See [#4256](https://github.com/activeadmin/activeadmin/issues/4256) for more details. +If your CSV export includes untrusted data provided by your users, it's possible +that they could include an executable formula that could call arbitrary commands +on your computer. See +[#4256](https://github.com/activeadmin/activeadmin/issues/4256) for more +details. ## Session Commits & Asset Pipeline @@ -28,13 +32,14 @@ find a solution. ### Helpers are not reloading in development -This is a known and still open [issue](https://github.com/activeadmin/activeadmin/issues/697) -the only way is to restart your server each time you change a helper. +This is a known and still open +[issue](https://github.com/activeadmin/activeadmin/issues/697) the only way is +to restart your server each time you change a helper. ### Helper maybe not included by default -If you use `config.action_controller.include_all_helpers = false` in your application config, -you need to include it by hand. +If you use `config.action_controller.include_all_helpers = false` in your +application config, you need to include it by hand. #### Solutions @@ -63,10 +68,13 @@ end ## CSS -In order to avoid the override of your application style with the Active Admin one, you can do one of these things: +In order to avoid the override of your application style with the Active Admin +one, you can do one of these things: -* You can properly move the generated file `active_admin.scss` from `app/assets/stylesheets` to `vendor/assets/stylesheets`. -* You can remove all `require_tree` commands from your root level css files, where the `active_admin.scss` is in the tree. +* You can properly move the generated file `active_admin.scss` from + `app/assets/stylesheets` to `vendor/assets/stylesheets`. +* You can remove all `require_tree` commands from your root level css files, + where the `active_admin.scss` is in the tree. ## Conflicts @@ -103,7 +111,10 @@ YourModel.solr_search ### Rails 5 scaffold generators -Active Admin requires the `inherited_resources` gem which may break scaffolding under Rails 5 as it replaces the default scaffold generator. The solution is to configure the default controller in `config/application.rb` as outlined in [activeadmin/inherited_resources#195](https://github.com/activeadmin/inherited_resources/issues/195) +Active Admin requires the `inherited_resources` gem which may break scaffolding +under Rails 5 as it replaces the default scaffold generator. The solution is to +configure the default controller in `config/application.rb` as outlined in +[activeadmin/inherited_resources#195](https://github.com/activeadmin/inherited_resources/issues/195) ``` module SampleApp @@ -117,4 +128,11 @@ end ## Authentication & Application Controller -The `ActiveAdmin::BaseController` inherits from the `ApplicationController`. Any authentication method(s) specified in the `ApplicationController` callbacks will be called instead of the authentication method in the active admin config file. For example, if the ApplicationController has a callback `before_action :custom_authentication_method` and the config file's authentication method is `config.authentication_method = :authenticate_active_admin_user`, then `custom_authentication_method` will be called instead of `authenticate_active_admin_user`. +The `ActiveAdmin::BaseController` inherits from the `ApplicationController`. Any +authentication method(s) specified in the `ApplicationController` callbacks will +be called instead of the authentication method in the active admin config file. +For example, if the ApplicationController has a callback `before_action +:custom_authentication_method` and the config file's authentication method is +`config.authentication_method = :authenticate_active_admin_user`, then +`custom_authentication_method` will be called instead of +`authenticate_active_admin_user`. diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index c3cba5b8a8a..fb358b224a1 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -28,8 +28,8 @@ ActiveAdmin.register Post do end ``` -Any form field that sends multiple values (such as a HABTM association, or an array attribute) -needs to pass an empty array to `permit_params`: +Any form field that sends multiple values (such as a HABTM association, or an +array attribute) needs to pass an empty array to `permit_params`: If your HABTM is `roles`, you should permit `role_ids: []` @@ -75,7 +75,8 @@ ActiveAdmin.register Post do end ``` -The `permit_params` call creates a method called `permitted_params`. You should use this method when overriding `create` or `update` actions: +The `permit_params` call creates a method called `permitted_params`. You should +use this method when overriding `create` or `update` actions: ```ruby ActiveAdmin.register Post do @@ -106,8 +107,10 @@ end ## Renaming Action Items -You can use translations to override labels and page titles for actions such as new, edit, and destroy by providing a resource specific translation. -For example, to change 'New Offer' to 'Make an Offer' add the following in config/locales/[en].yml: +You can use translations to override labels and page titles for actions such as +new, edit, and destroy by providing a resource specific translation. For +example, to change 'New Offer' to 'Make an Offer' add the following in +config/locales/[en].yml: ``` en: @@ -270,9 +273,15 @@ config.namespace :admin do |admin| menu.add label: "The Application", url: "/", priority: 0 menu.add label: "Sites" do |sites| - sites.add label: "Google", url: "http://google.com", html_options: { target: :blank } - sites.add label: "Facebook", url: "http://facebook.com" - sites.add label: "Github", url: "http://github.com" + sites.add label: "Google", + url: "http://google.com", + html_options: { target: :blank } + + sites.add label: "Facebook", + url: "http://facebook.com" + + sites.add label: "Github", + url: "http://github.com" end end end @@ -311,7 +320,8 @@ end ## Eager loading -A common way to increase page performance is to elimate N+1 queries by eager loading associations: +A common way to increase page performance is to elimate N+1 queries by eager +loading associations: ```ruby ActiveAdmin.register Post do @@ -321,10 +331,13 @@ end ## Customizing resource retrieval -Our controllers are built on [Inherited Resources](https://github.com/activeadmin/inherited_resources), -so you can use [all of its features](https://github.com/activeadmin/inherited_resources#overwriting-defaults). +Our controllers are built on [Inherited +Resources](https://github.com/activeadmin/inherited_resources), so you can use +[all of its +features](https://github.com/activeadmin/inherited_resources#overwriting-defaults). -If you need to customize the collection properties, you can overwrite the `scoped_collection` method. +If you need to customize the collection properties, you can overwrite the +`scoped_collection` method. ```ruby ActiveAdmin.register Post do @@ -336,8 +349,9 @@ ActiveAdmin.register Post do end ``` -If you need to completely replace the record retrieving code (e.g., you have a custom -`to_param` implementation in your models), override the `resource` method on the controller: +If you need to completely replace the record retrieving code (e.g., you have a +custom `to_param` implementation in your models), override the `resource` method +on the controller: ```ruby ActiveAdmin.register Post do @@ -349,8 +363,9 @@ ActiveAdmin.register Post do end ``` -Note that if you use an authorization library like CanCan, you should be careful to not -write code like this, otherwise **your authorization rules won't be applied**: +Note that if you use an authorization library like CanCan, you should be careful +to not write code like this, otherwise **your authorization rules won't be +applied**: ```ruby ActiveAdmin.register Post do diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index a272764a118..99496ac6c5c 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -110,8 +110,9 @@ To override options for string or numeric filter pass `filters` option. filter :title, filters: [:starts_with, :ends_with] ``` -Also, if you don't need the select with the options 'contains', 'equals', 'starts_with' or 'ends_with' -just add the option to the filter name with an underscore. +Also, if you don't need the select with the options 'contains', 'equals', +'starts_with' or 'ends_with' just add the option to the filter name with an +underscore. For example: @@ -129,9 +130,11 @@ filter :author, label: 'Something else' By default, Active Admin will try to use ActiveModel I18n to determine the label. -You can also filter on more than one attribute of a model using the -[Ransack search predicate syntax](https://github.com/activerecord-hackery/ransack/wiki/Basic-Searching). If using a custom search method, you will -also need to specify the field type using `:as` and the label. +You can also filter on more than one attribute of a model using the [Ransack +search predicate +syntax](https://github.com/activerecord-hackery/ransack/wiki/Basic-Searching). +If using a custom search method, you will also need to specify the field type +using `:as` and the label. ```ruby filter :first_name_or_last_name_cont, as: :string, label: "Name" @@ -183,8 +186,8 @@ remove_filter :id ## Index Scopes You can define custom scopes for your index page. This will add a tab bar above -the index table to quickly filter your collection on pre-defined scopes. There are -a number of ways to define your scopes: +the index table to quickly filter your collection on pre-defined scopes. There +are a number of ways to define your scopes: ```ruby scope :all, default: true @@ -202,12 +205,13 @@ scope ->{ Date.today.strftime '%A' }, :published_today scope("Inactive") { |scope| scope.where(active: false) } # conditionally show a custom controller scope -scope "Published", if: proc { current_admin_user.can? :manage, Posts } do |posts| +scope "Published", if: -> { current_admin_user.can? :manage, Posts } do |posts| posts.published end ``` -Scopes can be labelled with a translation, e.g. `activerecord.scopes.invoice.expired`. +Scopes can be labelled with a translation, e.g. +`activerecord.scopes.invoice.expired`. ## Index default sort order @@ -290,6 +294,9 @@ ActiveAdmin.setup do |config| end ``` -Note: you have to actually implement PDF rendering for your action, ActiveAdmin does not provide this feature. This setting just allows you to specify formats that you want to show up under the index collection. +Note: you have to actually implement PDF rendering for your action, ActiveAdmin +does not provide this feature. This setting just allows you to specify formats +that you want to show up under the index collection. -You'll need to use a PDF rendering library like PDFKit or WickedPDF to get the PDF generation you want. +You'll need to use a PDF rendering library like PDFKit or WickedPDF to get the +PDF generation you want. diff --git a/docs/3-index-pages/index-as-table.md b/docs/3-index-pages/index-as-table.md index c2cc4507f14..438348eb7a0 100644 --- a/docs/3-index-pages/index-as-table.md +++ b/docs/3-index-pages/index-as-table.md @@ -9,8 +9,9 @@ redirect_from: /docs/3-index-pages/index-as-table.html # Index as a Table -By default, the index page is a table with each of the models content columns and links to -show, edit and delete the object. There are many ways to customize what gets +By default, the index page is a table with each of the models content columns +and links to show, edit and delete the object. There are many ways to customize +what gets displayed. ## Defining Columns @@ -44,10 +45,12 @@ end ``` Sometimes that just isn't enough and you need to write some view-specific code. -For example, say we wanted a "Title" column that links to the posts admin screen. +For example, say we wanted a "Title" column that links to the posts admin +screen. -`column` accepts a block that will be rendered for each of the objects in the collection. -The block is called once for each resource, which is passed as an argument to the block. +`column` accepts a block that will be rendered for each of the objects in the +collection. The block is called once for each resource, which is passed as an +argument to the block. ```ruby index do @@ -118,7 +121,8 @@ index do end ``` -In addition, you can insert the position of the row in the greater collection by using the index_column special command: +In addition, you can insert the position of the row in the greater collection by +using the index_column special command: ```ruby index do @@ -128,7 +132,8 @@ index do end ``` -index_column take an optional offset parameter to allow a developer to set the starting number for the index (default is 1). +index_column take an optional offset parameter to allow a developer to set the +starting number for the index (default is 1). ## Sorting @@ -136,11 +141,12 @@ When a column is generated from an Active Record attribute, the table is sortable by default. If you are creating a custom column, you may need to give Active Admin a hint for how to sort the table. -If a column is defined using a block, you must pass the key to turn on sorting. The key -is the attribute which gets used to sort objects using Active Record. +If a column is defined using a block, you must pass the key to turn on sorting. +The key is the attribute which gets used to sort objects using Active Record. -By default, this is the column on the resource's table that the attribute corresponds to. -Otherwise, any attribute that the resource collection responds to can be used. +By default, this is the column on the resource's table that the attribute +corresponds to. Otherwise, any attribute that the resource collection responds +to can be used. ```ruby index do @@ -169,7 +175,8 @@ end ## Custom sorting -It is also possible to use database specific expressions and options for sorting by column +It is also possible to use database specific expressions and options for sorting +by column ```ruby order_by(:title) do |order_clause| @@ -224,8 +231,8 @@ end ## Custom row class -In order to add special class to table rows pass the proc object as a `:row_class` option -of the `index` method. +In order to add special class to table rows pass the proc object as a +`:row_class` option of the `index` method. ```ruby index row_class: ->elem { 'active' if elem.active? } do diff --git a/docs/5-forms.md b/docs/5-forms.md index 719abf6a237..39a8e8766d0 100644 --- a/docs/5-forms.md +++ b/docs/5-forms.md @@ -64,7 +64,8 @@ end This is a regular Rails partial so any template engine may be used. -You can also use the `ActiveAdmin::FormBuilder` as builder in your Formtastic Form for use the same helpers are used in the admin file: +You can also use the `ActiveAdmin::FormBuilder` as builder in your Formtastic +Form for use the same helpers are used in the admin file: ```ruby = semantic_form_for [:admin, @post], builder: ActiveAdmin::FormBuilder do |f| @@ -78,7 +79,8 @@ You can also use the `ActiveAdmin::FormBuilder` as builder in your Formtastic Fo ## Nested Resources -You can create forms with nested models using the `has_many` method, even if your model uses `has_one`: +You can create forms with nested models using the `has_many` method, even if +your model uses `has_one`: ```ruby ActiveAdmin.register Post do @@ -90,7 +92,9 @@ ActiveAdmin.register Post do end f.inputs 'Content', :body f.inputs do - f.has_many :categories, heading: 'Themes', allow_destroy: true, new_record: false do |a| + f.has_many :categories, heading: 'Themes', + allow_destroy: true, + new_record: false do |a| a.input :title end end @@ -100,8 +104,9 @@ ActiveAdmin.register Post do end end f.inputs do - f.has_many :comment, new_record: 'Leave Comment', - allow_destroy: proc { |comment| comment.author?(current_admin_user) } do |b| + f.has_many :comment, + new_record: 'Leave Comment', + allow_destroy: -> { |c| c.author?(current_admin_user) } do |b| b.input :body end end @@ -113,27 +118,44 @@ end The `:allow_destroy` option adds a checkbox to the end of the nested form allowing removal of the child object upon submission. Be sure to set `allow_destroy: true` -on the association to use this option. It is possible to associate `:allow_destroy` with a string or a symbol, corresponding to the name of a child object's method that will get called, or with a Proc object. The Proc object receives the child object as a parameter and should return either true or false. +on the association to use this option. It is possible to associate +`:allow_destroy` with a string or a symbol, corresponding to the name of a child +object's method that will get called, or with a Proc object. The Proc object +receives the child object as a parameter and should return either true or false. -The `:heading` option adds a custom heading. You can hide it entirely by passing `false`. +The `:heading` option adds a custom heading. You can hide it entirely by passing +`false`. -The `:new_record` option controls the visibility of the new record button (shown by default). -If you pass a string, it will be used as the text for the new record button. +The `:new_record` option controls the visibility of the new record button (shown +by default). If you pass a string, it will be used as the text for the new +record button. -The `:sortable` option adds a hidden field and will enable drag & drop sorting of the children. It -expects the name of the column that will store the index of each child. +The `:sortable` option adds a hidden field and will enable drag & drop sorting +of the children. It expects the name of the column that will store the index of +each child. -The `:sortable_start` option sets the value (0 by default) of the first position in the list. +The `:sortable_start` option sets the value (0 by default) of the first position +in the list. ## Datepicker -ActiveAdmin offers the `datepicker` input, which uses the [jQuery UI datepicker](http://jqueryui.com/datepicker/). -The datepicker input accepts any of the options available to the standard jQueryUI Datepicker. For example: +ActiveAdmin offers the `datepicker` input, which uses the [jQuery UI +datepicker](http://jqueryui.com/datepicker/). The datepicker input accepts any +of the options available to the standard jQueryUI Datepicker. For example: ```ruby form do |f| - f.input :starts_at, as: :datepicker, datepicker_options: { min_date: "2013-10-8", max_date: "+3D" } - f.input :ends_at, as: :datepicker, datepicker_options: { min_date: 3.days.ago.to_date, max_date: "+1W +5D" } + f.input :starts_at, as: :datepicker, + datepicker_options: { + min_date: "2013-10-8", + max_date: "+3D" + } + + f.input :ends_at, as: :datepicker, + datepicker_options: { + min_date: 3.days.ago.to_date, + max_date: "+1W +5D" + } end ``` @@ -177,8 +199,9 @@ You can arrange content in tabs as shown below: # Customize the Create Another checkbox -In order to simplify creating multiple resources you may enable ActiveAdmin to show nice "Create Another" checkbox alongside of Create Model -button. It may be enabled for the whole application: +In order to simplify creating multiple resources you may enable ActiveAdmin to +show nice "Create Another" checkbox alongside of Create Model button. It may be +enabled for the whole application: ```ruby ActiveAdmin.setup do |config| diff --git a/docs/6-show-pages.md b/docs/6-show-pages.md index b91d6a7c68e..4762cf657f6 100644 --- a/docs/6-show-pages.md +++ b/docs/6-show-pages.md @@ -3,7 +3,8 @@ redirect_from: /docs/6-show-pages.html --- # Customize the Show Page -The show block is rendered within the context of the view and uses [Arbre](https://github.com/activeadmin/arbre) syntax. +The show block is rendered within the context of the view and uses +[Arbre](https://github.com/activeadmin/arbre) syntax. With the `show` block, you can render anything you want. diff --git a/docs/7-sidebars.md b/docs/7-sidebars.md index 27719a97978..8ff0523bb29 100644 --- a/docs/7-sidebars.md +++ b/docs/7-sidebars.md @@ -68,7 +68,8 @@ By default sidebars are positioned in the same order as they defined, but it's a possible to specify their position manually: ```ruby -sidebar :help, priority: 0 # will push Help section to the top (above default Filters section) +# will push Help section to the top (above default Filters section) +sidebar :help, priority: 0 ``` Default sidebar priority is `10`. diff --git a/docs/8-custom-actions.md b/docs/8-custom-actions.md index 7a3aa33d950..65fbd3b57e9 100644 --- a/docs/8-custom-actions.md +++ b/docs/8-custom-actions.md @@ -139,7 +139,9 @@ end Actions items also accept the `:if` option to conditionally display them: ```ruby -action_item :super_action, only: :show, if: proc{ current_admin_user.super_admin? } do +action_item :super_action, + only: :show, + if: proc{ current_admin_user.super_admin? } do "Only display this to super admins on the show screen" end ``` diff --git a/docs/9-batch-actions.md b/docs/9-batch-actions.md index 3e09f817060..61f0c7417dd 100644 --- a/docs/9-batch-actions.md +++ b/docs/9-batch-actions.md @@ -154,7 +154,8 @@ batch_action :doit, form: -> { {user: User.pluck(:name, :id)} } do |ids, inputs| end ``` -Under the covers this is powered by the JS `ActiveAdmin.modal_dialog` which you can use yourself: +Under the covers this is powered by the JS `ActiveAdmin.modal_dialog` which you +can use yourself: ```coffee if $('body.admin_users').length diff --git a/docs/documentation.md b/docs/documentation.md index 5e3a91e214c..2cb669ca4c8 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -2,13 +2,14 @@ redirect_from: /docs/documentation.html --- -Active Admin is a framework for creating administration style interfaces. It abstracts common business application patterns to make it simple for developers to implement beautiful and elegant interfaces with very -little effort. +Active Admin is a framework for creating administration style interfaces. It +abstracts common business application patterns to make it simple for developers +to implement beautiful and elegant interfaces with very little effort. # Getting Started -Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby on Rails application. To - install, simply add the following to your Gemfile: +Active Admin is released as a Ruby Gem. The gem is to be installed within a Ruby +on Rails application. To install, simply add the following to your Gemfile: ```ruby # Gemfile @@ -21,7 +22,9 @@ After updating your bundle, run the installer rails generate active_admin:install ``` -The installer creates an initializer used for configuring defaults used by Active Admin as well as a new folder at `app/admin` to put all your admin configurations. +The installer creates an initializer used for configuring defaults used by +Active Admin as well as a new folder at `app/admin` to put all your admin +configurations. Migrate your db and start the server: @@ -44,7 +47,8 @@ $> rails generate active_admin:resource [MyModelName] ``` -This creates a file at `app/admin/my_model_names.rb` for configuring the resource. Refresh your web browser to see the interface. +This creates a file at `app/admin/my_model_names.rb` for configuring the +resource. Refresh your web browser to see the interface. # Next Steps From 85a284bc7efb8c75160ecc65d2c2dda8fa6871b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:32:30 -0300 Subject: [PATCH 0586/3836] Add missing backquote --- docs/13-authorization-adapter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/13-authorization-adapter.md b/docs/13-authorization-adapter.md index bc5b1caec46..a7aba2929d4 100644 --- a/docs/13-authorization-adapter.md +++ b/docs/13-authorization-adapter.md @@ -136,7 +136,7 @@ Each of these actions is available as a constant. Eg: `:read` is available as Active Admin provides a helper method to check if the current user is authorized to perform an action on a subject. -Simply use the `#authorized?(action, subject) method to check. +Simply use the `#authorized?(action, subject)` method to check. ```ruby ActiveAdmin.register Post do From 63dd5fd0eea3a4006484dbadef1499338c396f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:33:16 -0300 Subject: [PATCH 0587/3836] Better link --- docs/14-gotchas.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 68335027075..f6b8767f3f2 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -22,8 +22,8 @@ When configuring the asset pipeline ensure that the asset prefix session from being committed. Flash messages won't work and you will be unable to use the session for storing anything. -For more information see the following post: -[http://www.intridea.com/blog/2013/3/20/rails-assets-prefix-may-disable-your-session](http://www.intridea.com/blog/2013/3/20/rails-assets-prefix-may-disable-your-session) +For more information see [the following +post](http://www.intridea.com/blog/2013/3/20/rails-assets-prefix-may-disable-your-session) ## Helpers From f4815ea945e9d743b0f0911e6bead3f5706575e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 10 Jun 2017 13:34:24 -0300 Subject: [PATCH 0588/3836] Add missing dot after sentence --- docs/14-gotchas.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index f6b8767f3f2..294334e866e 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -23,7 +23,7 @@ session from being committed. Flash messages won't work and you will be unable t use the session for storing anything. For more information see [the following -post](http://www.intridea.com/blog/2013/3/20/rails-assets-prefix-may-disable-your-session) +post](http://www.intridea.com/blog/2013/3/20/rails-assets-prefix-may-disable-your-session). ## Helpers From 803a306146fc9329572c9255a9fa0ccfcf925f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 3 Jun 2017 14:38:11 -0300 Subject: [PATCH 0589/3836] New task for linting docs --- tasks/lint.rake | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tasks/lint.rake b/tasks/lint.rake index 25912e9c75f..8a02cd689d8 100644 --- a/tasks/lint.rake +++ b/tasks/lint.rake @@ -1,8 +1,14 @@ desc "Lints ActiveAdmin code base" -task lint: "lint:rubocop" +task lint: ["lint:rubocop", "lint:mdl"] namespace :lint do require "rubocop/rake_task" desc "Checks ruby code style with RuboCop" RuboCop::RakeTask.new + + desc "Checks markdown code style with Markdownlint" + task :mdl do + puts "Running mdl..." + system("mdl docs/*.md") + end end From f01434fe016c4cb167f89a2348516a968fb6eea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Mon, 12 Jun 2017 12:51:24 -0300 Subject: [PATCH 0590/3836] Unlock cucumber version in tests --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 6e7b79681d7..2ab8f6d74f0 100644 --- a/Gemfile +++ b/Gemfile @@ -44,7 +44,7 @@ group :test do gem 'simplecov', require: false # Test coverage generator. Go to /coverage/ after running tests gem 'codecov', require: false # Test coverage website. Go to https://codecov.io gem 'cucumber-rails', github: 'cucumber/cucumber-rails', require: false - gem 'cucumber', '1.3.20' + gem 'cucumber' gem 'database_cleaner' gem 'jasmine' gem 'jslint_on_rails' From 06e4db7a882232de01f692a9b924b3935f773e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 11 Jun 2017 18:23:33 -0300 Subject: [PATCH 0591/3836] Drop MRI 2.1 support --- .travis.yml | 7 ------- CHANGELOG.md | 4 ++++ activeadmin.gemspec | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25589f8639d..bafcf003467 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,6 @@ script: rvm: - jruby-9.1.10.0 - - 2.1.10 - 2.2.7 - 2.3.4 - 2.4.1 @@ -42,12 +41,6 @@ env: matrix: fast_finish: true - exclude: - - rvm: 2.1.10 - gemfile: gemfiles/rails_50.gemfile - - rvm: 2.1.10 - gemfile: gemfiles/rails_51.gemfile - allow_failures: - rvm: jruby-9.1.10.0 gemfile: gemfiles/rails_50.gemfile diff --git a/CHANGELOG.md b/CHANGELOG.md index f658eee4331..87737740a33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Master (unreleased) +### Removals + +* Ruby 2.1 support has been dropped [#5002][] by [@deivid-rodriguez][] + ### Deprecations * Deprecated `type` param from `status_tag` and related CSS classes [#4989][] by [@javierjulio][] diff --git a/activeadmin.gemspec b/activeadmin.gemspec index b88cba82545..43fe3b332ba 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.test_files = `git ls-files -- {spec,features}/*`.split("\n") - s.required_ruby_version = '>= 2.1' + s.required_ruby_version = '>= 2.2' s.add_dependency 'arbre', '>= 1.1.1' s.add_dependency 'bourbon' From 1287d6a4d24b54047b90a20f7ad0bdbfcce92cca Mon Sep 17 00:00:00 2001 From: vytenis Date: Mon, 12 Jun 2017 12:38:30 +0300 Subject: [PATCH 0592/3836] added missing lt translations --- config/locales/lt.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 45bc79e21ed..6716d1b74da 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -31,6 +31,15 @@ lt: ends_with: "Baigiasi" greater_than: 'didesnis nei' less_than: 'mažiau nei' + gteq_datetime: "daugiau arba lygu nei" + lteq_datetime: "mažiau arba lygu nei" + from: "Nuo" + to: "Iki" + search_status: + headline: "Paieškos būsena:" + current_scope: "Apimtis:" + current_filters: "Esami filtrai:" + no_current_filters: "nėra" status_tag: "yes": "Taip" "no": "Nėra" @@ -39,12 +48,14 @@ lt: powered_by: "Powered by %{active_admin} %{version}" sidebars: filters: 'Filtrai' + search_status: "Paieškos būsena" pagination: empty: '%{model} nerastas' one: 'Rodoma 1 %{model}' one_page: 'Rodoma visi %{n} %{model}' multiple: 'Rodomi %{model} %{iš} - %{to} %{total} iš viso' multiple_without_total: 'Rodomi %{model} %{iš} - %{to} ' + per_page: "Puslapyje: " entry: one: 'įrašas' other: 'įrašai' @@ -60,18 +71,20 @@ lt: delete_confirmation: 'Ar jūs tikrai norite pašalinti šiuos %{plural_model}?' succesfully_destroyed: one: 'Sėkmingai pašalintas 1 %{model}' - few: 'Sėkmingai pašalinti %{count} %{plural_model}' other: 'Sėkmingai pašalinti %{count} %{plural_model}' selection_toggle_explanation: '(Žymėti)' action_label: '%{title} Pasirinkta' labels: destroy: 'Šalinti' comments: + created_at: "Sukurta" resource_type: 'Resurso Tipas' author_type: 'Autoriaus Tipas' body: 'Įrašas' author: 'Autorius' add: 'Pridėti komentarą' + delete: "Trinti komentarą" + delete_confirmation: "Ar tikrai norite ištrinti šį komentarą?" resource: 'Išteklių' no_comments_yet: 'Dar nėra komentarų.' author_missing: 'Anonimas' @@ -87,6 +100,8 @@ lt: title: 'Subdomenas' password: title: 'Slaptažodis' + password_confirmation: + title: "Pakartokite slaptažodį" sign_up: title: 'Registracija' submit: 'Užsiregistruoti' @@ -105,11 +120,18 @@ lt: submit: 'Pakartotinai siųsti atrakinimo instrukcijas' resend_confirmation_instructions: title: 'Patvirtinimo Instrukcijos' - submit: 'Siųsti patvirtinimo instructions' + submit: 'Siųsti patvirtinimo instrukcijas' links: + sign_up: "Užsiregistruoti" sign_in: 'Prisijungti' forgot_your_password: 'Pamiršote slaptažodį?' sign_in_with_omniauth_provider: 'Prisijungti su %{provider}' + resend_unlock_instructions: "Persiųsti pakartotinio atrakinimo instrukcijas" + resend_confirmation_instructions: "Persiųsti patvirtinimo instrukcijas" + unsupported_browser: + headline: "Atkreipiame dėmesį, kad ActiveAdmin nebepalaiko Internet Explorer 8 arba žemesnių versijų." + recommendation: "Rekomenduojame atsinaujinti į naujausią Internet Explorer, Google Chrome, arba Firefox." + turn_off_compatibility_view: "Jei naudojate IE 9 ar vėlesnę versiją, įsitikinkite kad išjungėte \"Suderinamumo rodinį\"." access_denied: message: 'Jūs nesate įgaliotas atlikti šį veiksmą.' index_list: From 4c625a5a09e5fd49c4476cd16435cdcb70daf140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 14 Jun 2017 11:21:40 -0300 Subject: [PATCH 0593/3836] Remove IRC notifications stuff We don't really use this. --- .travis.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index bafcf003467..942eecb25a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,15 +46,3 @@ matrix: gemfile: gemfiles/rails_50.gemfile - rvm: jruby-9.1.10.0 gemfile: gemfiles/rails_51.gemfile - -notifications: - irc: - channels: - - irc.freenode.org#activeadmin - - on_success: change - on_failure: always - skip_join: true - - template: - - "(%{branch}/%{commit} by %{author}): %{message} (%{build_url})" From 5f9d1680ea4a49f708162b52842fe9d8f7c010f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 14 Jun 2017 11:22:15 -0300 Subject: [PATCH 0594/3836] Try out trusty containers --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 942eecb25a5..2d1043ec70b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ language: ruby sudo: false +dist: trusty + bundler_args: --without development branches: From f52614999e078c0a170d026c769b7384e868f0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Jun 2017 17:00:14 -0300 Subject: [PATCH 0595/3836] Remove gcov from codecov's config Not applicable to us. --- codecov.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/codecov.yml b/codecov.yml index 5366f75f9f7..776f0ea9eb8 100644 --- a/codecov.yml +++ b/codecov.yml @@ -13,11 +13,5 @@ coverage: patch: true project: true parsers: - gcov: - branch_detection: - conditional: true - loop: true - macro: false - method: false javascript: enable_partials: false From 6aa8fc05ecc8281cbf95ef055b4cae7b376d82ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Jun 2017 17:52:56 -0300 Subject: [PATCH 0596/3836] Require step definitions inside env.rb file This will be useful to track coverage of step files themselves. --- cucumber.yml | 6 +++--- features/support/env.rb | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cucumber.yml b/cucumber.yml index 4fdbfaac3ce..ffaeda60b60 100644 --- a/cucumber.yml +++ b/cucumber.yml @@ -1,3 +1,3 @@ -default: --format 'progress' --require features/support/env.rb --require features/step_definitions features --tags ~@requires-reloading --tags ~@wip -wip: --format 'progress' --require features/support/env.rb --require features/step_definitions features --tags @wip:3 --wip features -class-reloading: CLASS_RELOADING=true --format 'progress' --require features/support/env.rb --require features/step_definitions features --tags @requires-reloading +default: --format 'progress' --require features/support/env.rb features --tags ~@requires-reloading --tags ~@wip +wip: --format 'progress' --require features/support/env.rb features --tags @wip:3 --wip features +class-reloading: CLASS_RELOADING=true --format 'progress' --require features/support/env.rb features --tags @requires-reloading diff --git a/features/support/env.rb b/features/support/env.rb index 6007ff3584d..22ab244f58a 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -8,6 +8,10 @@ require File.expand_path('../../../spec/spec_helper', __FILE__) +Dir["#{File.expand_path('../../step_definitions', __FILE__)}/*.rb"].each do |f| + require f +end + require 'rails' ENV['RAILS_ROOT'] = File.expand_path("../../../spec/rails/rails-#{Rails.version}", __FILE__) From c37c13ff9a6e99e59e925da22926a5297f751bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Jun 2017 17:54:07 -0300 Subject: [PATCH 0597/3836] Fix cucumber features coverage merging We need to give different names to the runs, so that reports are properly merged instead of overwritten. --- cucumber.yml | 4 ++-- features/support/regular_env.rb | 5 +++++ features/support/reload_env.rb | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 features/support/regular_env.rb create mode 100644 features/support/reload_env.rb diff --git a/cucumber.yml b/cucumber.yml index ffaeda60b60..cbb7fa6030e 100644 --- a/cucumber.yml +++ b/cucumber.yml @@ -1,3 +1,3 @@ -default: --format 'progress' --require features/support/env.rb features --tags ~@requires-reloading --tags ~@wip +default: --format 'progress' --require features/support/regular_env.rb features --tags ~@requires-reloading --tags ~@wip wip: --format 'progress' --require features/support/env.rb features --tags @wip:3 --wip features -class-reloading: CLASS_RELOADING=true --format 'progress' --require features/support/env.rb features --tags @requires-reloading +class-reloading: CLASS_RELOADING=true --format 'progress' --require features/support/reload_env.rb features --tags @requires-reloading diff --git a/features/support/regular_env.rb b/features/support/regular_env.rb new file mode 100644 index 00000000000..38969751fe9 --- /dev/null +++ b/features/support/regular_env.rb @@ -0,0 +1,5 @@ +require 'simplecov' + +SimpleCov.command_name "regular features" + +require_relative 'env' diff --git a/features/support/reload_env.rb b/features/support/reload_env.rb new file mode 100644 index 00000000000..9175d449518 --- /dev/null +++ b/features/support/reload_env.rb @@ -0,0 +1,5 @@ +require 'simplecov' + +SimpleCov.command_name "reload features" + +require_relative 'env' From 287a2205bda149857f60f37e6547fa83538384e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Jun 2017 17:59:45 -0300 Subject: [PATCH 0598/3836] Remove unnecessary require --- spec/unit/menu_item_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/unit/menu_item_spec.rb b/spec/unit/menu_item_spec.rb index 72aaadf3e38..b05b311297a 100644 --- a/spec/unit/menu_item_spec.rb +++ b/spec/unit/menu_item_spec.rb @@ -1,4 +1,3 @@ -require 'spec_helper' require 'active_admin/menu' require 'active_admin/menu_item' From e0286b95e1a65296c69b66a1a2a4f38c42638500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Jun 2017 18:01:14 -0300 Subject: [PATCH 0599/3836] Configure simplecov in the standard place --- .simplecov | 16 ++++++++++++++++ features/support/env.rb | 2 +- spec/spec_helper.rb | 15 --------------- 3 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 .simplecov diff --git a/.simplecov b/.simplecov new file mode 100644 index 00000000000..cd33dd6047b --- /dev/null +++ b/.simplecov @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# @todo: Always run simplecov again once +# https://github.com/colszowka/simplecov/issues/404, +# https://github.com/glebm/i18n-tasks/issues/221 are fixed +if ENV['COVERAGE'] == 'true' + SimpleCov.start do + add_filter 'spec/' + add_filter 'features/' + end +end + +if ENV['CI'] == 'true' + require 'codecov' + SimpleCov.formatter = SimpleCov::Formatter::Codecov +end diff --git a/features/support/env.rb b/features/support/env.rb index 22ab244f58a..2aa371e453d 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -6,7 +6,7 @@ ENV['RAILS_ENV'] = 'test' -require File.expand_path('../../../spec/spec_helper', __FILE__) +require 'simplecov' Dir["#{File.expand_path('../../step_definitions', __FILE__)}/*.rb"].each do |f| require f diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ffafb2c1dcc..6d75bd08304 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,16 +1 @@ require 'simplecov' - -# @todo: Always run simplecov again once -# https://github.com/colszowka/simplecov/issues/404, -# https://github.com/glebm/i18n-tasks/issues/221 are fixed -if ENV['COVERAGE'] == 'true' - SimpleCov.start do - add_filter 'spec/' - add_filter 'features/' - end -end - -if ENV['CI'] == 'true' - require 'codecov' - SimpleCov.formatter = SimpleCov::Formatter::Codecov -end From 2f391a0091955e664a7780de3539e8496602e878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Jun 2017 18:01:50 -0300 Subject: [PATCH 0600/3836] Stop ignoring spec folders for coverage tracking We still want to ignore the test app folder though. --- .simplecov | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.simplecov b/.simplecov index cd33dd6047b..4db8e6a1a01 100644 --- a/.simplecov +++ b/.simplecov @@ -5,8 +5,7 @@ # https://github.com/glebm/i18n-tasks/issues/221 are fixed if ENV['COVERAGE'] == 'true' SimpleCov.start do - add_filter 'spec/' - add_filter 'features/' + add_filter 'spec/rails/' end end From 7c77e42c249515a0b8c61b3a26bd835bee72d704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 9 Jun 2017 18:03:15 -0300 Subject: [PATCH 0601/3836] Remove unnecessary spec tasks This can be just run thorough ``` bundle exec rspec spec/requests ``` instead of ``` bundle exec rake spec:request ``` which is almost as concise and benefits from autocompletion :) --- tasks/test.rake | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tasks/test.rake b/tasks/test.rake index 6658fd67afa..609e017ca21 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,5 +1,5 @@ desc "Run the full suite using 1 core" -task test: ['spec:unit', 'spec:request', 'cucumber', 'cucumber:class_reloading'] +task test: ['spec', 'cucumber', 'cucumber:class_reloading'] desc "Run the full suite against all supported Rails versions using 1 core" task :test_all do @@ -19,20 +19,6 @@ require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -namespace :spec do - - desc "Run the unit specs" - RSpec::Core::RakeTask.new(:unit) do |t| - t.pattern = "spec/unit/**/*_spec.rb" - end - - desc "Run the request specs" - RSpec::Core::RakeTask.new(:request) do |t| - t.pattern = "spec/requests/**/*_spec.rb" - end - -end - require 'cucumber/rake/task' Cucumber::Rake::Task.new(:cucumber) do |t| From 3e2ef8f3d642bc990dde00d2e4be356f452d647a Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 15 Jun 2017 21:31:31 +0300 Subject: [PATCH 0602/3836] do not pass humanize_name option to CSV when exporting [fixes #5010] --- features/index/format_as_csv.feature | 17 +++++++++++++++++ lib/active_admin/csv_builder.rb | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/features/index/format_as_csv.feature b/features/index/format_as_csv.feature index e9ada33d2ff..df3b6b9936b 100644 --- a/features/index/format_as_csv.feature +++ b/features/index/format_as_csv.feature @@ -61,6 +61,23 @@ Feature: Format as CSV | Title | Body | | Hello, World | (.*) | + Scenario: With humanize_name option + Given a configuration of: + """ + ActiveAdmin.register Post do + csv humanize_name: false do + column :title + column :body + end + end + """ + And a post with the title "Hello, World" exists + When I am on the index page for posts + And I follow "CSV" + And I should download a CSV file with "," separator for "posts" containing: + | title | body | + | Hello, World | (.*) | + Scenario: With CSV option customization Given a configuration of: """ diff --git a/lib/active_admin/csv_builder.rb b/lib/active_admin/csv_builder.rb index 55e49a7ebeb..6c98374f511 100644 --- a/lib/active_admin/csv_builder.rb +++ b/lib/active_admin/csv_builder.rb @@ -45,7 +45,7 @@ def build(controller, csv) options = ActiveAdmin.application.csv_options.merge self.options bom = options.delete :byte_order_mark column_names = options.delete(:column_names) { true } - csv_options = options.except :encoding_options + csv_options = options.except :encoding_options, :humanize_name csv << bom if bom From f0adeddb71ee10f4c1b1c234c334cb622a20185e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 10:00:01 +0200 Subject: [PATCH 0603/3836] Revert "Merge pull request #4931 from activeadmin/mention_bot" This reverts commit fee94b9ad170717ac5917534154f2202675cc151, reversing changes made to c5b7746e15071d7a2e0a0d4cfbf19e8c1e699583. The configuration added is not really working and I came to think Varyonic was right. --- .mention-bot | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .mention-bot diff --git a/.mention-bot b/.mention-bot deleted file mode 100644 index b327ef5c9b6..00000000000 --- a/.mention-bot +++ /dev/null @@ -1,9 +0,0 @@ -{ - "message": "@pullRequester, thanks for contributing an activeadmin - translation! @reviewers, are you able to review this?", - "findPotentialReviewers": true, - "actions": ["labeled"], - "createComment": true, - "withLabel": "i18n", - "delayed": false -} From 3c480dfd833d86f05eaba994bb00da2246afa17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 12:01:58 +0200 Subject: [PATCH 0604/3836] Update unsupported browser recommendation Link to browsehappy.com as a simpler alternative. Idea & message by @javierjulio. --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index f39ab1c9d6d..6c5f88d9f56 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -131,7 +131,7 @@ en: resend_confirmation_instructions: "Resend confirmation instructions" unsupported_browser: headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." - recommendation: "We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox." + recommendation: "We recommend that you upgrade your browser to improve your experience." turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." access_denied: message: "You are not authorized to perform this action." From 2420cf6e995727ddd87dde3f4b5517cd89536099 Mon Sep 17 00:00:00 2001 From: Mauricio Pasquier Juan Date: Sat, 17 Jun 2017 16:10:15 -0300 Subject: [PATCH 0605/3836] Missing es keys, minor fixes --- config/locales/es.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index d0fd5ea56f2..dc7767b479f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -8,6 +8,7 @@ es: edit: "Editar" delete: "Eliminar" delete_confirmation: "¿Está seguro de que quiere eliminar esto?" + create_another: "Crear otro %{model}" new_model: "Añadir %{model}" edit_model: "Editar %{model}" delete_model: "Eliminar %{model}" @@ -31,6 +32,10 @@ es: ends_with: "Termina con" greater_than: "Mayor que" less_than: "Menor que" + gteq_datetime: "Mayor o igual que" + lteq_datetime: "Menor o igual que" + from: "Desde" + to: "Hasta" search_status: headline: "Estado de la búsqueda:" current_scope: "Alcance:" @@ -51,6 +56,7 @@ es: one_page: "Mostrando un total de %{n} %{model}" multiple: "Mostrando %{model} %{from} - %{to} de un total de %{total}" multiple_without_total: "Mostrando %{model} %{from} - %{to}" + per_page: "Por página: " entry: one: "registro" other: "registros" @@ -94,7 +100,9 @@ es: subdomain: title: "Subdominio" password: - title: "Password" + title: "Contraseña" + password_confirmation: + title: "Confirmar Contraseña" sign_up: title: "Registrarse" submit: "Registrarse" From 916c36aff66b06d655d294d7c5df2feaa80643f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 09:49:43 +0200 Subject: [PATCH 0606/3836] Unlock bundler version in CI Just install the latest version, since it now appears more stable, and our dependencies are a lot simpler now. --- .travis.yml | 3 +-- CONTRIBUTING.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d1043ec70b..99e790146b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,7 @@ before_install: - PATH=$(npm bin):$PATH # needed to install phantomjs via npm - if [ $(phantomjs --version) != '2.1.1' ]; then npm install phantomjs-prebuilt@2.1; fi - gem update --system # use the very latest Rubygems - - rvm @global do gem uninstall bundler -a -x - - rvm @global do gem install bundler -v 1.14.6 # latest version known to work + - gem install bundler # use the very latest Bundler script: - bundle exec rake diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64b399c0383..fff57a682e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,8 +27,7 @@ git checkout -b 325-add-japanese-translations ### 3. Get the test suite running Make sure you're using a recent ruby and have the `bundler` gem installed, at -least version `1.14.3`. The most reliable `bundler` version to use is the same -Travis is using. +least version `1.14.3`. Install the development dependencies: From e7fb3a017c33b46917f58d41ddc29dfb1ec06c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 10:55:15 +0200 Subject: [PATCH 0607/3836] Bump jruby again See if it improves performance. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99e790146b2..a35bddade4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ script: - bundle exec rake rvm: - - jruby-9.1.10.0 + - jruby-9.1.12.0 - 2.2.7 - 2.3.4 - 2.4.1 @@ -43,7 +43,7 @@ matrix: fast_finish: true allow_failures: - - rvm: jruby-9.1.10.0 + - rvm: jruby-9.1.12.0 gemfile: gemfiles/rails_50.gemfile - - rvm: jruby-9.1.10.0 + - rvm: jruby-9.1.12.0 gemfile: gemfiles/rails_51.gemfile From 9b056341a85304b7c5f71ed15bd8e627f3c8e229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 21:12:55 +0200 Subject: [PATCH 0608/3836] Recommend the default rake task in CONTRIBUTING.md Since it runs linters as well. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fff57a682e4..c86daaadc70 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,7 @@ bundle install Now you should be able to run the entire suite using: ```sh -bundle exec rake test +bundle exec rake ``` This will automatically run the tests against Rails 5.0. But you can easily run From 6dc6ea3ae78ad90638bcbe6b23b3ac8f3acafe3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 18 Jun 2017 15:21:43 +0200 Subject: [PATCH 0609/3836] No need to point to unreleased cucumber-rails --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 2ab8f6d74f0..c1d1b5ca301 100644 --- a/Gemfile +++ b/Gemfile @@ -43,7 +43,7 @@ group :test do gem 'capybara' gem 'simplecov', require: false # Test coverage generator. Go to /coverage/ after running tests gem 'codecov', require: false # Test coverage website. Go to https://codecov.io - gem 'cucumber-rails', github: 'cucumber/cucumber-rails', require: false + gem 'cucumber-rails', require: false gem 'cucumber' gem 'database_cleaner' gem 'jasmine' From 0b228c36a59740344a8c7659944b826a9b17ac86 Mon Sep 17 00:00:00 2001 From: humancopy Date: Tue, 6 Jun 2017 13:23:36 +0200 Subject: [PATCH 0610/3836] Fix Hebrew translations --- config/locales/he.yml | 54 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/config/locales/he.yml b/config/locales/he.yml index 881663f1d5c..484db099373 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -8,6 +8,7 @@ he: edit: "עריכה" delete: "מחיקה" delete_confirmation: "האם אתה בטוח שאתה רוצה למחוק את זה?" + create_another: "צור עוד %{model}" new_model: "%{model} חדש" edit_model: "ערוך %{model}" delete_model: "מחיקת %{model}" @@ -31,20 +32,29 @@ he: ends_with: "מסתיים ב" greater_than: "גדול מ" less_than: "פחות מ" + gteq_datetime: "אחרי או בתאריך" + lteq_datetime: "לפני או בתאריך" + search_status: + headline: "תוצאות חיפוש:" + current_scope: "תחום:" + current_filters: "מסננים:" + no_current_filters: "ללא" status_tag: "yes": "כן" "no": "לא" - main_content: "Please implement %{model}#main_content to display content." + main_content: "אנא הטמע את %{model}#main_content בכדי להציג תוכן." logout: "התנתקות" powered_by: "Powered by %{active_admin} %{version}" sidebars: filters: "סינון" + search_status: "מצב החיפוש" pagination: empty: "אין %{model} בנמצא" one: "מציג 1 %{model}" one_page: "הצגת כל %{n} %{model}" multiple: "מציג %{model} %{from} - %{to} מתוך %{total} בסך הכל" multiple_without_total: "מציג %{model} %{from} - %{to}" + per_page: "בדף: " entry: one: "רשומה בודדה" other: "רשומות" @@ -60,23 +70,40 @@ he: delete_confirmation: "האם הנך בטוח שאתה רוצה למרוח את %{plural_model}?" succesfully_destroyed: one: "1 %{model} נמחק בהצלחה" - few: "%{count} %{plural_model} נמחק בהצלחה" - many: "%{count} %{plural_model} נמחק בהצלחה" other: "%{count} %{plural_model} נמחק בהצלחה" selection_toggle_explanation: "(שינוי בחירה)" action_label: "%{title} נבחר" labels: destroy: "מחק" comments: + created_at: "נוצר" + resource_type: "סוג רישום" + author_type: "סוג מחבר" body: "תוכן" author: 'נוצר ע"י' add: "הוסף תגובה" + delete: "מחק תגובה" + delete_confirmation: "האם אתה בטוח שברצונך למחוק תגובה זאת?" resource: "Resource" no_comments_yet: "אין עדיין תגובות." + author_missing: "אנונימי" title_content: "תגובות (%{count})" errors: empty_text: "התגובה לא נשמרה, שדה התוכן ריק." devise: + username: + title: "שם משתמש" + email: + title: "כתובת דוא״ל" + subdomain: + title: "תת-דומיין" + password: + title: "סיסמא" + password_confirmation: + title: "אישור סיסמא" + sign_up: + title: "הרשמה" + submit: "הרשמה" login: title: "כניסה" remember_me: "זכור אותי" @@ -87,7 +114,28 @@ he: change_password: title: "שנה את הסיסמא שלך" submit: "שנה את הסיסמא שלי" + unlock: + title: "שלח שוב הוראות שיחרור" + submit: "שלח שוב הוראות שיחרור" + resend_confirmation_instructions: + title: "שלח שוב הוראות אישור" + submit: "שלח שוב הוראות אישור" links: + sign_up: "הרשמה" sign_in: "כניסה" forgot_your_password: "שכחת את הסיסמא שלך?" sign_in_with_omniauth_provider: "%{provider} היכנס עם" + resend_unlock_instructions: "שלח שוב הוראות שיחרור" + resend_confirmation_instructions: "שלח שוב הוראות אישור" + unsupported_browser: + headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." + recommendation: "We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox." + turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." + access_denied: + message: "אתה לא רשאי לבצע פעולה זו." + index_list: + table: "טבלה" + block: "רשימה" + grid: "גריד" + blog: "בלוג" + From cab33a517e6338237989f8aa69e8984e9dc18767 Mon Sep 17 00:00:00 2001 From: humancopy Date: Wed, 7 Jun 2017 18:11:05 +0200 Subject: [PATCH 0611/3836] More Hebrew translations --- config/locales/he.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/he.yml b/config/locales/he.yml index 484db099373..28217f7b0b8 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -44,7 +44,7 @@ he: "no": "לא" main_content: "אנא הטמע את %{model}#main_content בכדי להציג תוכן." logout: "התנתקות" - powered_by: "Powered by %{active_admin} %{version}" + powered_by: "ממונע בעזרת %{active_admin} %{version}" sidebars: filters: "סינון" search_status: "מצב החיפוש" @@ -84,7 +84,7 @@ he: add: "הוסף תגובה" delete: "מחק תגובה" delete_confirmation: "האם אתה בטוח שברצונך למחוק תגובה זאת?" - resource: "Resource" + resource: "רשומה" no_comments_yet: "אין עדיין תגובות." author_missing: "אנונימי" title_content: "תגובות (%{count})" @@ -128,11 +128,11 @@ he: resend_unlock_instructions: "שלח שוב הוראות שיחרור" resend_confirmation_instructions: "שלח שוב הוראות אישור" unsupported_browser: - headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." - recommendation: "We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox." - turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." + headline: "שים לב ש-ActiveAdmin אינו תומך יותר ב-Internet Explorer גרסא 8 ומטה." + recommendation: "אנו ממליצים לשדרג לגרסא האחרונה של Internet Explorer, Google Chrome, או Firefox." + turn_off_compatibility_view: "אם אתה משתמש ב- IE 9 ואילך, ודא שכיבית \"תצוגת תאימות\"." access_denied: - message: "אתה לא רשאי לבצע פעולה זו." + message: "אינך רשאי לבצע פעולה זו." index_list: table: "טבלה" block: "רשימה" From fa15c79d7da58cf9bd02eaf2f844756df5e936f7 Mon Sep 17 00:00:00 2001 From: humancopy Date: Wed, 7 Jun 2017 18:26:36 +0200 Subject: [PATCH 0612/3836] Fix outdated links to unsupported_browser.turn_off_compatibility_view and localise them --- config/locales/ar.yml | 2 +- config/locales/da.yml | 2 +- config/locales/de-CH.yml | 2 +- config/locales/de.yml | 2 +- config/locales/el.yml | 2 +- config/locales/en-CA.yml | 2 +- config/locales/en-GB.yml | 2 +- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- config/locales/he.yml | 2 +- config/locales/id.yml | 2 +- config/locales/it.yml | 2 +- config/locales/ja.yml | 2 +- config/locales/nl.yml | 2 +- config/locales/pt-BR.yml | 2 +- config/locales/ru.yml | 2 +- config/locales/sv-SE.yml | 2 +- config/locales/uk.yml | 2 +- config/locales/zh-TW.yml | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index ed85108b696..3b27cabf73a 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -124,7 +124,7 @@ ar: unsupported_browser: headline: "يُرجى مُلاحظة أن (أكتف أدمن) لم تعد تدعم المُتصفّح إنترنت اكسبلوررالإصدار الثامن وما قبله" recommendation: "ننصح بالتحديث إلى الإصدارات الأخيرة من: Internet Explorer, Google Chrome, أو Firefox." - turn_off_compatibility_view: "إن كنت تستخدم الإصدار التاسع وما يليه من إنترنت إكسبلورر تأكّد من تعطيل \"Compatibility View\"." + turn_off_compatibility_view: "إن كنت تستخدم الإصدار التاسع وما يليه من إنترنت إكسبلورر تأكّد من تعطيل \"Compatibility View\"." access_denied: message: "لم يُصرّح لك بهذا الإجراء." index_list: diff --git a/config/locales/da.yml b/config/locales/da.yml index 290a9d679ca..1933d8cb753 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -126,7 +126,7 @@ da: unsupported_browser: headline: "Vær venligst opmærksom på, at ActiveAdmin ikke længere understøtter Internet Explorer version 8 eller tidligere." recommendation: "Vi anbefaler at du opgraderer til den nyeste Internet Explorer, Google Chrome, eller Firefox." - turn_off_compatibility_view: "Hvis du bruger IE 9 eller senere, så vær sikker på, at du slår \"Compatibility View\" fra." + turn_off_compatibility_view: "Hvis du bruger IE 9 eller senere, så vær sikker på, at du slår \"Compatibility View\" fra." access_denied: message: "Du har ikke rettigheder til at udføre denne handling." index_list: diff --git a/config/locales/de-CH.yml b/config/locales/de-CH.yml index c7415f3488e..41703ca7540 100644 --- a/config/locales/de-CH.yml +++ b/config/locales/de-CH.yml @@ -97,4 +97,4 @@ unsupported_browser: headline: "ActiveAdmin unterstützt nicht länger den Internet Explorer in Version 8 oder niedriger." recommendation: "Wir empfehlen die Nutzung von Internet Explorer, Google Chrome, oder Firefox." - turn_off_compatibility_view: "Wenn sie IE 9 oder neuer benutzen, stellen sie sicher das sie den \"Kompatibilitätsansicht\" ausgeschaltet haben." + turn_off_compatibility_view: "Wenn sie IE 9 oder neuer benutzen, stellen sie sicher das sie den \"Kompatibilitätsansicht\" ausgeschaltet haben." diff --git a/config/locales/de.yml b/config/locales/de.yml index d8d19c4ca61..3526e851571 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -123,7 +123,7 @@ de: unsupported_browser: headline: "ActiveAdmin unterstützt nicht länger den Internet Explorer in Version 8 oder niedriger." recommendation: "Wir empfehlen die Nutzung von Internet Explorer, Google Chrome, oder Firefox." - turn_off_compatibility_view: "Wenn sie IE 9 oder neuer benutzen, stellen sie sicher das sie den \"Kompatibilitätsansicht\" ausgeschaltet haben." + turn_off_compatibility_view: "Wenn sie IE 9 oder neuer benutzen, stellen sie sicher das sie den \"Kompatibilitätsansicht\" ausgeschaltet haben." access_denied: message: "Sie haben nicht die Berechtigung um diese Aktion auszuführen." index_list: diff --git a/config/locales/el.yml b/config/locales/el.yml index fee15e01db2..701154dbcbc 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -115,7 +115,7 @@ el: unsupported_browser: headline: "Το ActiveAdmin δεν υποστηρίζει πλεον τον Internet Explorer έκδοση 8 η μικρότερη." recommendation: "Σας προτείνουμε να αναβαθμίσετε στην τελευταία Internet Explorer, Google Chrome, or Firefox." - turn_off_compatibility_view: "Αν χρησιμοποιείτε IE 9 ή μεγαλύτερη έκδοση, σιγουρευτείτε ότι turn off \"Compatibility View\"." + turn_off_compatibility_view: "Αν χρησιμοποιείτε IE 9 ή μεγαλύτερη έκδοση, σιγουρευτείτε ότι turn off \"Compatibility View\"." access_denied: message: "Δεν έχετε πρόσβαση για αυτή την ενέργεια." index_list: diff --git a/config/locales/en-CA.yml b/config/locales/en-CA.yml index d4027c18be2..2148ea13577 100644 --- a/config/locales/en-CA.yml +++ b/config/locales/en-CA.yml @@ -128,7 +128,7 @@ unsupported_browser: headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." recommendation: "We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox." - turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." + turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." access_denied: message: "You are not authorized to perform this action." index_list: diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index da63bae56f0..ebf189df1bc 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -128,7 +128,7 @@ unsupported_browser: headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." recommendation: "We recommend upgrading to the latest Internet Explorer, Google Chrome, or Firefox." - turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." + turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." access_denied: message: "You are not authorised to perform this action." index_list: diff --git a/config/locales/en.yml b/config/locales/en.yml index 6c5f88d9f56..728624352a6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -132,7 +132,7 @@ en: unsupported_browser: headline: "Please note that ActiveAdmin no longer supports Internet Explorer versions 8 or less." recommendation: "We recommend that you upgrade your browser to improve your experience." - turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." + turn_off_compatibility_view: "If you are using IE 9 or later, make sure you turn off \"Compatibility View\"." access_denied: message: "You are not authorized to perform this action." index_list: diff --git a/config/locales/es.yml b/config/locales/es.yml index dc7767b479f..83034d2cef1 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -132,7 +132,7 @@ es: unsupported_browser: headline: "Por favor tenga en cuenta que Active Admin no soporta versiones de Internet Explorer menores a 8." recommendation: "Recomendamos que actualice a la última versión de Internet Explorer, Google Chrome, o Firefox." - turn_off_compatibility_view: "Si está usando IE 9 o superior, asegúrese de apagar la \"Vista de compatibilidad\"." + turn_off_compatibility_view: "Si está usando IE 9 o superior, asegúrese de apagar la \"Vista de compatibilidad\"." access_denied: message: "No está autorizado/a a realizar esta acción." index_list: diff --git a/config/locales/he.yml b/config/locales/he.yml index 28217f7b0b8..5de02c5b8b2 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -129,7 +129,7 @@ he: resend_confirmation_instructions: "שלח שוב הוראות אישור" unsupported_browser: headline: "שים לב ש-ActiveAdmin אינו תומך יותר ב-Internet Explorer גרסא 8 ומטה." - recommendation: "אנו ממליצים לשדרג לגרסא האחרונה של Internet Explorer, Google Chrome, או Firefox." + recommendation: "אנו ממליצים לשדרג את הדפדפן שלך על מנת לשפר את חווית הגלישה." turn_off_compatibility_view: "אם אתה משתמש ב- IE 9 ואילך, ודא שכיבית \"תצוגת תאימות\"." access_denied: message: "אינך רשאי לבצע פעולה זו." diff --git a/config/locales/id.yml b/config/locales/id.yml index f6ceb197eb6..9b46b9abdbe 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -124,7 +124,7 @@ id: unsupported_browser: headline: "Harap dicatat bahwa ActiveAdmin sudah tidak mendukung InternetExplorer versi 8 atau versi sebelum itu." recommendation: "Kami sarankan agar anda mengupgrade ke versi Internet Explorer, Google Chrome, atau Firefox yang terbaru." - turn_off_compatibility_view: "Kalau anda menggunakan IE 9 atau yang lebih baru, pastikan anda mematikan \"Compatibility View\"." + turn_off_compatibility_view: "Kalau anda menggunakan IE 9 atau yang lebih baru, pastikan anda mematikan \"Compatibility View\"." access_denied: message: "Anda tidak diperkenankan melakukan aksi tersebut." index_list: diff --git a/config/locales/it.yml b/config/locales/it.yml index ba5a036a44a..bee43d9a30d 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -124,7 +124,7 @@ it: unsupported_browser: headline: "Perfavore, notare che ActiveAdmin non supporta più Internet Explorer 8 o inferiore" recommendation: "Ti raccomandiamo di aggiornare alla versione più recente di Internet Explorer, Google Chrome, o Firefox." - turn_off_compatibility_view: "Se stai utilizzando Internet Explorer 9 o successivo, assicurati di disabilitare la \"Modalità Compatibilità\"." + turn_off_compatibility_view: "Se stai utilizzando Internet Explorer 9 o successivo, assicurati di disabilitare la \"Modalità Compatibilità\"." access_denied: message: "Non hai le autorizzazioni necessarie per eseguire questa azione." index_list: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 5a3562cb6e7..272fbc808f5 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -125,7 +125,7 @@ ja: unsupported_browser: headline: "ActiveAdminは、Internet Explorer 8以下はサポートはしていません。" recommendation: "最新版のInternet ExplorerGoogle Chrome、もしくはFirefoxを使うことを推奨します。" - turn_off_compatibility_view: "Internet Explorer 9以降を使っている場合、互換表示をオフにしてください。" + turn_off_compatibility_view: "Internet Explorer 9以降を使っている場合、互換表示をオフにしてください。" access_denied: message: "アクションを実行する権限がありません" index_list: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 4ec1adf3dfc..cf19d62ed41 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -122,7 +122,7 @@ nl: unsupported_browser: headline: "Opgelet, ActiveAdmin bied geen support meer voor Internet Explorer 8 of lager" recommendation: "Wij raden aan om te upgraden naar de nieuwste Internet Explorer, Google Chrome, of Firefox." - turn_off_compatibility_view: "Als u IE 9 of nieuwer gebruikt, zorg ervoor dat u \"Compatibility View\" uit zet." + turn_off_compatibility_view: "Als u IE 9 of nieuwer gebruikt, zorg ervoor dat u \"Compatibility View\" uit zet." access_denied: message: "U bent niet gemachtigd voor deze actie." index_list: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index eb67f16ede0..d254bf7cc66 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -124,7 +124,7 @@ pt-BR: unsupported_browser: headline: "O ActiveAdmin não oferece suporte ao Internet Explorer versão 8 ou inferior." recommendation: "Nós recomendamos atualizar para a última versão do Internet Explorer, Google Chrome, ou Firefox." - turn_off_compatibility_view: "Se você está usando o IE 9 ou superior, desligue o \"Modo de Exibição de Compatibilidade\"." + turn_off_compatibility_view: "Se você está usando o IE 9 ou superior, desligue o \"Modo de Exibição de Compatibilidade\"." access_denied: message: "Você não tem permissão para realizar o solicitado" index_list: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 4d376435591..377c09851e6 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -128,7 +128,7 @@ ru: unsupported_browser: headline: "Пожалуйста, обратите внимание, что Active Admin больше не поддерживает старые версии Internet Explorer начиная с версии IE 8" recommendation: "Мы рекомендуем обновить версию вашего браузера (Internet Explorer, Google Chrome, или Firefox)." - turn_off_compatibility_view: "Если вы используете IE 9 или новее, убедитесь, что вы выключили опцию \"Просмотр в режиме совместимости\"." + turn_off_compatibility_view: "Если вы используете IE 9 или новее, убедитесь, что вы выключили опцию \"Просмотр в режиме совместимости\"." access_denied: message: "Вы не авторизованы для выполнения данного действия." index_list: diff --git a/config/locales/sv-SE.yml b/config/locales/sv-SE.yml index a87c1439228..c45f12aac5f 100644 --- a/config/locales/sv-SE.yml +++ b/config/locales/sv-SE.yml @@ -122,7 +122,7 @@ unsupported_browser: headline: "Notera att ActiveAdmin inte längre stödjer Internet Explorer version 8 eller mindre." recommendation: "Vi rekommenderar dig att uppgradera till den senaste versionen av Internet Explorer, Google Chrome, eller Firefox." - turn_off_compatibility_view: "Om du använder IE 9 eller senare, se till att stäng av \"Compatibility View\"." + turn_off_compatibility_view: "Om du använder IE 9 eller senare, se till att stäng av \"Compatibility View\"." access_denied: message: "Du har inte rättighet att utföra denna åtgärd." index_list: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 422bd05be22..63cde356365 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -125,7 +125,7 @@ uk: unsupported_browser: headline: "Зверніть, будь-ласка, увагу, що ActiveAdmin більше не підтримує Internet Explorer 8 версії і нижче" recommendation: "Ми рекомендуємо оновити версію вашого браузеру (Internet Explorer, Google Chrome, або Firefox)." - turn_off_compatibility_view: "Якщо ви використовуєте IE 9 і вище, переконайтесь, що ви вимкнули опцію \"Перегляд в режимі сумісності\"." + turn_off_compatibility_view: "Якщо ви використовуєте IE 9 і вище, переконайтесь, що ви вимкнули опцію \"Перегляд в режимі сумісності\"." access_denied: message: "Ви не авторизовані для виконання даної дії." index_list: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index abd1213aca3..5e9b2e01281 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -124,7 +124,7 @@ unsupported_browser: headline: "很抱歉,ActiveAdmin 已不再支援 Internet Explorer 8 以下版本的瀏覽器。" recommendation: "建議您升級到最新版本的Internet ExplorerGoogle Chrome,或是 Firefox。" - turn_off_compatibility_view: "若您是使用 IE 9 或更新的版本,請確認「相容性檢視」是關閉的。" + turn_off_compatibility_view: "若您是使用 IE 9 或更新的版本,請確認「相容性檢視」是關閉的。" access_denied: message: "您沒有權限執行此項操作" index_list: From 2165c41c62cd5fae0fea5f4b2dbc62c8ad7ca037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 10:34:35 +0200 Subject: [PATCH 0613/3836] Remove jslint It's unmantained, it was skipped unless java was installed and it was not analyzing any files! --- Gemfile | 1 - spec/requests/javascript_spec.rb | 22 --------- spec/support/jslint.yml | 80 -------------------------------- 3 files changed, 103 deletions(-) delete mode 100644 spec/requests/javascript_spec.rb delete mode 100644 spec/support/jslint.yml diff --git a/Gemfile b/Gemfile index 2ab8f6d74f0..a65b85685af 100644 --- a/Gemfile +++ b/Gemfile @@ -47,7 +47,6 @@ group :test do gem 'cucumber' gem 'database_cleaner' gem 'jasmine' - gem 'jslint_on_rails' gem 'launchy' gem 'rails-i18n' # Provides default i18n for many languages gem 'rspec-rails' diff --git a/spec/requests/javascript_spec.rb b/spec/requests/javascript_spec.rb deleted file mode 100644 index d0c2bd4597a..00000000000 --- a/spec/requests/javascript_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'rails_helper' -require 'jslint' -require 'rbconfig' - -# OSX has its own java executable that opens a prompt to install Java 💩 -# However this java_home executable returns an error code without opening the prompt ✅ -RbConfig::CONFIG['host_os'].include?('darwin') ? `/usr/libexec/java_home` : `which java` -java_installed = $?.success? - -RSpec.describe 'Javascript', type: :request, if: java_installed do - let(:lint) { - JSLint::Lint.new \ - paths: ['public/javascripts/**/*.js'], - exclude_paths: ['public/javascripts/vendor/**/*.js'], - config_path: 'spec/support/jslint.yml' - } - - it 'should not have any syntax errors' do - lint.run - end -end - diff --git a/spec/support/jslint.yml b/spec/support/jslint.yml deleted file mode 100644 index ffe3a51269e..00000000000 --- a/spec/support/jslint.yml +++ /dev/null @@ -1,80 +0,0 @@ -# ------------ rake task options ------------ - -# JS files to check by default, if no parameters are passed to rake jslint -# (you may want to limit this only to your own scripts and exclude any external scripts and frameworks) - -# this can be overridden by adding 'paths' and 'exclude_paths' parameter to rake command: -# rake jslint paths=path1,path2,... exclude_paths=library1,library2,... - -paths: - - app/assets/javascripts/active_admin/**/*.js - -exclude_paths: - - app/assets/javascripts/active_admin/vendor.js - -# ------------ jslint options ------------ -# see http://www.jslint.com/lint.html#options for more detailed explanations - -# "enforce" type options (true means potentially more warnings) - -adsafe: false # true if ADsafe rules should be enforced. See http://www.ADsafe.org/ -bitwise: true # true if bitwise operators should not be allowed -newcap: true # true if Initial Caps must be used with constructor functions -eqeqeq: false # true if === should be required (for ALL equality comparisons) -immed: false # true if immediate function invocations must be wrapped in parens -nomen: false # true if initial or trailing underscore in identifiers should be forbidden -onevar: false # true if only one var statement per function should be allowed -plusplus: false # true if ++ and -- should not be allowed -regexp: false # true if . and [^...] should not be allowed in RegExp literals -safe: false # true if the safe subset rules are enforced (used by ADsafe) -strict: false # true if the ES5 "use strict"; pragma is required -undef: false # true if variables must be declared before used -white: false # true if strict whitespace rules apply (see also 'indent' option) - -# "allow" type options (false means potentially more warnings) - -cap: false # true if upper case HTML should be allowed -css: true # true if CSS workarounds should be tolerated -debug: false # true if debugger statements should be allowed (set to false before going into production) -es5: false # true if ECMAScript 5 syntax should be allowed -evil: false # true if eval should be allowed -forin: true # true if unfiltered 'for in' statements should be allowed -fragment: true # true if HTML fragments should be allowed -laxbreak: false # true if statement breaks should not be checked -on: false # true if HTML event handlers (e.g. onclick="...") should be allowed -sub: false # true if subscript notation may be used for expressions better expressed in dot notation - -# other options - -maxlen: 300 # Maximum line length -indent: 2 # Number of spaces that should be used for indentation - used only if 'white' option is set -maxerr: 50 # The maximum number of warnings reported (per file) -passfail: false # true if the scan should stop on first error (per file) -# following are relevant only if undef = true -predef: '' # Names of predefined global variables - comma-separated string or a YAML array -browser: true # true if the standard browser globals should be predefined -rhino: false # true if the Rhino environment globals should be predefined -windows: false # true if Windows-specific globals should be predefined -widget: false # true if the Yahoo Widgets globals should be predefined -devel: true # true if functions like alert, confirm, console, prompt etc. are predefined - - -# ------------ jslint_on_rails custom lint options (switch to true to disable some annoying warnings) ------------ - -# ignores "missing semicolon" warning at the end of a function; this lets you write one-liners -# like: x.map(function(i) { return i + 1 }); without having to put a second semicolon inside the function -lastsemic: false - -# allows you to use the 'new' expression as a statement (without assignment) -# so you can call e.g. new Ajax.Request(...), new Effect.Highlight(...) without assigning to a dummy variable -newstat: false - -# ignores the "Expected an assignment or function call and instead saw an expression" warning, -# if the expression contains a proper statement and makes sense; this lets you write things like: -# element && element.show(); -# valid || other || lastChance || alert('OMG!'); -# selected ? show() : hide(); -# although these will still cause a warning: -# element && link; -# selected ? 5 : 10; -statinexp: false From d9a9e02c4f2de8d9e15ebac0408f347575156ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 18 Jun 2017 20:43:41 +0200 Subject: [PATCH 0614/3836] Remove all the magic Just tell contributors to set their BUNDLE_GEMFILE environment variable to their target Rails version. Most of the patches won't need tests to be run locally against all supported version, so letting Travis guard for that seems good enough. --- CONTRIBUTING.md | 46 +++++++++++++++++----------------------------- Rakefile | 15 ++------------- tasks/test.rake | 14 -------------- 3 files changed, 19 insertions(+), 56 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c86daaadc70..259bd2c139b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,30 +29,24 @@ git checkout -b 325-add-japanese-translations Make sure you're using a recent ruby and have the `bundler` gem installed, at least version `1.14.3`. -Install the development dependencies: +Select the Gemfile for your preferred Rails version, preferably the latest: ```sh -bundle install +export BUNDLE_GEMFILE=gemfiles/rails_51.gemfile ``` -Now you should be able to run the entire suite using: +Now install the development dependencies: ```sh -bundle exec rake +bundle install ``` -This will automatically run the tests against Rails 5.0. But you can easily run -tests against older versions of Rails too by changing the `Gemfile` bundler -uses. - -Run, for example, +Now you should be able to run the entire suite using: -``` -export BUNDLE_GEMFILE=gemfiles/rails_42.gemfile +```sh +bundle exec rake ``` -And then everything will be run against Rails 4.2. - The test run will generate a sample Rails application in `spec/rails` to run the tests against. @@ -116,20 +110,7 @@ Or to migrate the database: bundle exec rake local db:migrate ``` -### 7. Run tests against major supported Rails versions - -Once you've implemented your code, got the tests passing, previewed it in a -browser, you're ready to test it against multiple versions of Rails. - -```sh -bundle exec rake test_all -``` - -This runs our test suite against a couple of major versions of Rails. -Travis does essentially the same thing when you open a Pull Request. -We care about quality, so your PR won't be merged until all tests pass. - -### 8. Make a Pull Request +### 7. Make a Pull Request At this point, you should switch back to your master branch and make sure it's up to date with Active Admin's master branch: @@ -152,7 +133,14 @@ Finally, go to GitHub and [make a Pull Request](https://help.github.com/articles/creating-a-pull-request) :D -### 9. Keeping your Pull Request updated +Travis CI will run our test suite against all supported Rails versions. We care +about quality, so your PR won't be merged until all tests pass. It's unlikely, +but it's possible that your changes pass tests in one Rails version but fail in +another. In that case, you'll have to setup your development environment (as +explained in step 3) to use the problematic Rails version, and investigate +what's going on! + +### 8. Keeping your Pull Request updated If a maintainer asks you to "rebase" your PR, they're saying that a lot of code has changed, and that you need to update your branch so it's easier to merge. @@ -168,7 +156,7 @@ git pull --rebase upstream master git push --force-with-lease 325-add-japanese-translations ``` -### 10. Merging a PR (maintainers only) +### 9. Merging a PR (maintainers only) A PR can only be merged into master by a maintainer if: diff --git a/Rakefile b/Rakefile index 1a08cffa2e4..15ff5096902 100644 --- a/Rakefile +++ b/Rakefile @@ -1,18 +1,7 @@ require 'bundler/gem_tasks' -task :enforce_version do - if ENV['BUNDLE_GEMFILE'] == File.expand_path('../Gemfile', __FILE__) - gemfile_path = File.expand_path('../gemfiles/rails_51.gemfile', __FILE__) - - command = ['bundle', 'exec', 'rake', *ARGV].join(' ') - env = { 'BUNDLE_GEMFILE' => gemfile_path } - - Bundler.with_clean_env { Kernel.exec(env, command) } - end -end - desc 'Creates a test rails app for the specs to run against' -task :setup, [:parallel, :dir, :template] => [:enforce_version] do |_t, opts| +task :setup, [:parallel, :dir, :template] do |_t, opts| require 'rails/version' base_dir = opts[:dir] || 'spec/rails' @@ -45,7 +34,7 @@ end # Import all our rake tasks FileList['tasks/**/*.rake'].each { |task| import task } -task default: [:enforce_version, :test, :lint] +task default: [:test, :lint] begin require 'jasmine' diff --git a/tasks/test.rake b/tasks/test.rake index 609e017ca21..46dd157a67e 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,20 +1,6 @@ desc "Run the full suite using 1 core" task test: ['spec', 'cucumber', 'cucumber:class_reloading'] -desc "Run the full suite against all supported Rails versions using 1 core" -task :test_all do - Dir.glob("gemfiles/rails_*.gemfile").each do |gemfile| - print "\n=== Running tests using #{gemfile} ===\n\n" - - Bundler.with_clean_env do - system({ "BUNDLE_GEMFILE" => gemfile }, "bundle check") || - system({ "BUNDLE_GEMFILE" => gemfile }, "bundle install") - - system({ "BUNDLE_GEMFILE" => gemfile }, "bundle exec rake test") - end - end -end - require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) From c83719a492acdbd9373dcdca5215566233c6a420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 18 Jun 2017 20:48:02 +0200 Subject: [PATCH 0615/3836] Simplify cucumber tasks --- tasks/test.rake | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tasks/test.rake b/tasks/test.rake index 46dd157a67e..3c197d8e2db 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,5 +1,5 @@ desc "Run the full suite using 1 core" -task test: ['spec', 'cucumber', 'cucumber:class_reloading'] +task test: ['spec', 'cucumber'] require 'rspec/core/rake_task' @@ -7,19 +7,21 @@ RSpec::Core::RakeTask.new(:spec) require 'cucumber/rake/task' -Cucumber::Rake::Task.new(:cucumber) do |t| - t.profile = 'default' - t.bundler = false -end +task cucumber: [:"cucumber:regular", :"cucumber:reloading"] namespace :cucumber do + Cucumber::Rake::Task.new(:regular, "Run the standard cucumber scenarios") do |t| + t.profile = 'default' + t.bundler = false + end + Cucumber::Rake::Task.new(:wip, "Run the cucumber scenarios with the @wip tag") do |t| t.profile = 'wip' t.bundler = false end - Cucumber::Rake::Task.new(:class_reloading, "Run the cucumber scenarios that test reloading") do |t| + Cucumber::Rake::Task.new(:reloading, "Run the cucumber scenarios that test reloading") do |t| t.profile = 'class-reloading' t.bundler = false end From 16aadc08c58e0c93822dbd3784c2b3006217c02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 21:08:33 +0200 Subject: [PATCH 0616/3836] Prefer symbols for simple tasks --- tasks/test.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/test.rake b/tasks/test.rake index 3c197d8e2db..2ffe62709cf 100644 --- a/tasks/test.rake +++ b/tasks/test.rake @@ -1,5 +1,5 @@ desc "Run the full suite using 1 core" -task test: ['spec', 'cucumber'] +task test: [:spec, :cucumber] require 'rspec/core/rake_task' From affb128cbcc88e9ad80bbeb0a6f9497b605df0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 09:54:13 +0200 Subject: [PATCH 0617/3836] Fix bad namespace for cop --- .rubocop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 2f4821a4bcd..14295ad64ef 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -61,7 +61,7 @@ Layout/TrailingWhitespace: Layout/SpaceAfterComma: Enabled: true -Style/SpaceAroundEqualsInParameterDefault: +Layout/SpaceAroundEqualsInParameterDefault: Enabled: true Layout/SpaceInsideParens: From dedc739e7274767abe4cebfa91720f0d844a88fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 09:55:50 +0200 Subject: [PATCH 0618/3836] Add Layout/TrailingBlankLines and fix offenses --- .rubocop.yml | 3 +++ features/step_definitions/action_link_steps.rb | 1 - features/step_definitions/filter_steps.rb | 2 +- features/step_definitions/format_steps.rb | 2 +- lib/active_admin/filters/active_sidebar.rb | 1 - lib/active_admin/inputs/filters/text_input.rb | 1 - lib/active_admin/resource/attributes.rb | 2 +- lib/active_admin/view_helpers/scope_name_helper.rb | 2 +- lib/active_admin/views/components/index_list.rb | 2 -- lib/active_admin/views/components/scopes.rb | 2 +- spec/support/templates/policies/active_admin/comment_policy.rb | 2 +- spec/support/templates/policies/active_admin/page_policy.rb | 2 +- spec/support/templates/policies/application_policy.rb | 2 +- spec/support/templates/post_decorator.rb | 1 - spec/unit/filters/active_filter_spec.rb | 2 +- spec/unit/helpers/scope_chain_spec.rb | 1 - spec/unit/resource/attributes_spec.rb | 1 - spec/unit/resource/ordering_spec.rb | 2 -- spec/unit/view_helpers/flash_helper_spec.rb | 1 - spec/unit/view_helpers/form_helper_spec.rb | 1 - 20 files changed, 12 insertions(+), 21 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 14295ad64ef..b53cf0ea82e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -55,6 +55,9 @@ Style/PredicateName: - has_many - has_many_actions +Layout/TrailingBlankLines: + Enabled: true + Layout/TrailingWhitespace: Enabled: true diff --git a/features/step_definitions/action_link_steps.rb b/features/step_definitions/action_link_steps.rb index bcc030208eb..355f9ecc0c8 100644 --- a/features/step_definitions/action_link_steps.rb +++ b/features/step_definitions/action_link_steps.rb @@ -17,4 +17,3 @@ Then /^I should not see a dropdown menu item to "([^"]*)"$/ do |name| %{Then I should not see "#{name}" within "ul.dropdown_menu_list li a"} end - diff --git a/features/step_definitions/filter_steps.rb b/features/step_definitions/filter_steps.rb index c7b1fdecfba..80a1ef329b5 100644 --- a/features/step_definitions/filter_steps.rb +++ b/features/step_definitions/filter_steps.rb @@ -45,4 +45,4 @@ Then /^I should see link "([^"]*)" in current filters/ do |label| expect(page).to have_css "li.current_filter b a", text: label -end \ No newline at end of file +end diff --git a/features/step_definitions/format_steps.rb b/features/step_definitions/format_steps.rb index 093a5a53ac2..78762b31340 100644 --- a/features/step_definitions/format_steps.rb +++ b/features/step_definitions/format_steps.rb @@ -53,4 +53,4 @@ Then /^access denied$/ do expect(page).to have_content(I18n.t("active_admin.access_denied.message")) -end \ No newline at end of file +end diff --git a/lib/active_admin/filters/active_sidebar.rb b/lib/active_admin/filters/active_sidebar.rb index bf89081bd38..461b87a078a 100644 --- a/lib/active_admin/filters/active_sidebar.rb +++ b/lib/active_admin/filters/active_sidebar.rb @@ -48,4 +48,3 @@ def sidebar_options end end end - diff --git a/lib/active_admin/inputs/filters/text_input.rb b/lib/active_admin/inputs/filters/text_input.rb index f67d60a7fa7..4cce984ca91 100644 --- a/lib/active_admin/inputs/filters/text_input.rb +++ b/lib/active_admin/inputs/filters/text_input.rb @@ -23,4 +23,3 @@ def to_html end end end - diff --git a/lib/active_admin/resource/attributes.rb b/lib/active_admin/resource/attributes.rb index 48063ddfa12..546ad6a08f3 100644 --- a/lib/active_admin/resource/attributes.rb +++ b/lib/active_admin/resource/attributes.rb @@ -41,4 +41,4 @@ def counter_cache_col?(c) end end -end \ No newline at end of file +end diff --git a/lib/active_admin/view_helpers/scope_name_helper.rb b/lib/active_admin/view_helpers/scope_name_helper.rb index 70dd787f3eb..d10cb90757d 100644 --- a/lib/active_admin/view_helpers/scope_name_helper.rb +++ b/lib/active_admin/view_helpers/scope_name_helper.rb @@ -13,4 +13,4 @@ def scope_name(scope) end end -end \ No newline at end of file +end diff --git a/lib/active_admin/views/components/index_list.rb b/lib/active_admin/views/components/index_list.rb index 03c8fd40aa8..34f8366533d 100644 --- a/lib/active_admin/views/components/index_list.rb +++ b/lib/active_admin/views/components/index_list.rb @@ -67,5 +67,3 @@ def current_filter_search_empty? end end end - - diff --git a/lib/active_admin/views/components/scopes.rb b/lib/active_admin/views/components/scopes.rb index 8c967f24139..31ba82f4fe7 100644 --- a/lib/active_admin/views/components/scopes.rb +++ b/lib/active_admin/views/components/scopes.rb @@ -62,4 +62,4 @@ def get_scope_count(scope) end end -end \ No newline at end of file +end diff --git a/spec/support/templates/policies/active_admin/comment_policy.rb b/spec/support/templates/policies/active_admin/comment_policy.rb index 948e7e97379..3488929e4ff 100644 --- a/spec/support/templates/policies/active_admin/comment_policy.rb +++ b/spec/support/templates/policies/active_admin/comment_policy.rb @@ -6,4 +6,4 @@ def resolve end end end -end \ No newline at end of file +end diff --git a/spec/support/templates/policies/active_admin/page_policy.rb b/spec/support/templates/policies/active_admin/page_policy.rb index 0f20fbead53..8a55a8177b7 100644 --- a/spec/support/templates/policies/active_admin/page_policy.rb +++ b/spec/support/templates/policies/active_admin/page_policy.rb @@ -15,4 +15,4 @@ def show? end end end -end \ No newline at end of file +end diff --git a/spec/support/templates/policies/application_policy.rb b/spec/support/templates/policies/application_policy.rb index fbdbb99f0eb..2879e42cb57 100644 --- a/spec/support/templates/policies/application_policy.rb +++ b/spec/support/templates/policies/application_policy.rb @@ -41,4 +41,4 @@ def destroy_all? def scope Pundit.policy_scope!(user, record.class) end -end \ No newline at end of file +end diff --git a/spec/support/templates/post_decorator.rb b/spec/support/templates/post_decorator.rb index 786231a6988..21745b47371 100644 --- a/spec/support/templates/post_decorator.rb +++ b/spec/support/templates/post_decorator.rb @@ -8,4 +8,3 @@ def decorator_method 'A method only available on the decorator' end end - diff --git a/spec/unit/filters/active_filter_spec.rb b/spec/unit/filters/active_filter_spec.rb index 43a8db96ff5..211bf2d78ac 100644 --- a/spec/unit/filters/active_filter_spec.rb +++ b/spec/unit/filters/active_filter_spec.rb @@ -87,4 +87,4 @@ end -end \ No newline at end of file +end diff --git a/spec/unit/helpers/scope_chain_spec.rb b/spec/unit/helpers/scope_chain_spec.rb index d4041addbc5..0f080c1a0e8 100644 --- a/spec/unit/helpers/scope_chain_spec.rb +++ b/spec/unit/helpers/scope_chain_spec.rb @@ -33,4 +33,3 @@ end end end - diff --git a/spec/unit/resource/attributes_spec.rb b/spec/unit/resource/attributes_spec.rb index 603edcea9a2..0c8cf63b45f 100644 --- a/spec/unit/resource/attributes_spec.rb +++ b/spec/unit/resource/attributes_spec.rb @@ -47,4 +47,3 @@ module ActiveAdmin end end - diff --git a/spec/unit/resource/ordering_spec.rb b/spec/unit/resource/ordering_spec.rb index 5529f3d3d9c..d78a198907c 100644 --- a/spec/unit/resource/ordering_spec.rb +++ b/spec/unit/resource/ordering_spec.rb @@ -33,5 +33,3 @@ module ActiveAdmin end end end - - diff --git a/spec/unit/view_helpers/flash_helper_spec.rb b/spec/unit/view_helpers/flash_helper_spec.rb index c70f0dbbd04..b3541b658c5 100644 --- a/spec/unit/view_helpers/flash_helper_spec.rb +++ b/spec/unit/view_helpers/flash_helper_spec.rb @@ -22,4 +22,3 @@ end end - diff --git a/spec/unit/view_helpers/form_helper_spec.rb b/spec/unit/view_helpers/form_helper_spec.rb index 5779239caef..5b68894e18c 100644 --- a/spec/unit/view_helpers/form_helper_spec.rb +++ b/spec/unit/view_helpers/form_helper_spec.rb @@ -40,4 +40,3 @@ end end end - From c93297cec111bfbff9fb2fafddb94c67f2eba940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 10:05:04 +0200 Subject: [PATCH 0619/3836] Add Style/Encoding cop and fix offenses --- .rubocop.yml | 4 ++++ spec/unit/csv_builder_spec.rb | 2 -- spec/unit/page_spec.rb | 2 -- spec/unit/routing_spec.rb | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b53cf0ea82e..a8f590c522a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -35,6 +35,10 @@ Layout/EndOfLine: Layout/ExtraSpacing: Enabled: true +Style/Encoding: + EnforcedStyle: never + Enabled: true + Style/HashSyntax: Enabled: true diff --git a/spec/unit/csv_builder_spec.rb b/spec/unit/csv_builder_spec.rb index e52d0823130..fa0b333f3a3 100644 --- a/spec/unit/csv_builder_spec.rb +++ b/spec/unit/csv_builder_spec.rb @@ -1,5 +1,3 @@ -# Encoding: UTF-8 - require 'rails_helper' RSpec.describe ActiveAdmin::CSVBuilder do diff --git a/spec/unit/page_spec.rb b/spec/unit/page_spec.rb index 0052ab6ef4e..02675051d7b 100644 --- a/spec/unit/page_spec.rb +++ b/spec/unit/page_spec.rb @@ -1,5 +1,3 @@ -# encoding: utf-8 - require 'rails_helper' require File.expand_path('config_shared_examples', File.dirname(__FILE__)) diff --git a/spec/unit/routing_spec.rb b/spec/unit/routing_spec.rb index cae2f30917c..9b1833908b0 100644 --- a/spec/unit/routing_spec.rb +++ b/spec/unit/routing_spec.rb @@ -1,5 +1,3 @@ -# encoding: utf-8 - require 'rails_helper' RSpec.describe ActiveAdmin, "Routing", type: :routing do From 7942971d1b0628c9bc2890f899eaabb544f9a5b5 Mon Sep 17 00:00:00 2001 From: Sasha Bichkov Date: Fri, 23 Jun 2017 12:37:47 +0300 Subject: [PATCH 0620/3836] Fix the interaction between batch actions --- app/assets/javascripts/active_admin/lib/batch_actions.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee index 1a9f787b7bf..90684674c33 100644 --- a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee +++ b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee @@ -14,7 +14,7 @@ $(document).on 'ready page:load turbolinks:load', -> $('.batch_actions_selector li a').on 'confirm:complete', (e, inputs)-> if val = JSON.stringify inputs - $('#batch_action_inputs').val val + $('#batch_action_inputs').removeAttr('disabled').val val else $('#batch_action_inputs').attr 'disabled', 'disabled' From a7e115f1a0021c5a556bb3a1c42ea809819adcd4 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Fri, 23 Jun 2017 11:15:41 +0300 Subject: [PATCH 0621/3836] skip polymorphic associations when detecting class in active filters [refs #5027] --- lib/active_admin/filters/active_filter.rb | 4 ++- spec/unit/filters/active_filter_spec.rb | 37 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/active_admin/filters/active_filter.rb b/lib/active_admin/filters/active_filter.rb index 4ca1f71125a..8d3c17003f8 100644 --- a/lib/active_admin/filters/active_filter.rb +++ b/lib/active_admin/filters/active_filter.rb @@ -66,7 +66,9 @@ def find_class if condition_attribute.klass != resource_class && condition_attribute.klass.primary_key == name.to_s condition_attribute.klass else - assoc = condition_attribute.klass.reflect_on_all_associations.detect { |r| r.foreign_key.to_s == name.to_s } + assoc = condition_attribute.klass.reflect_on_all_associations. + reject { |r| r.options[:polymorphic] }. #skip polymorphic + detect { |r| r.foreign_key.to_s == name.to_s } assoc.class_name.constantize if assoc end end diff --git a/spec/unit/filters/active_filter_spec.rb b/spec/unit/filters/active_filter_spec.rb index 43a8db96ff5..78507e7d53f 100644 --- a/spec/unit/filters/active_filter_spec.rb +++ b/spec/unit/filters/active_filter_spec.rb @@ -49,6 +49,43 @@ end + context 'search by polymorphic association' do + let(:resource) do + namespace.register(ActiveAdmin::Comment) + end + + let(:search) do + ActiveAdmin::Comment.ransack(resource_id_eq: post.id, resource_type_eq: post.class.to_s) + end + + context 'id filter' do + let(:condition) do + search.conditions[0] + end + it 'should have valid values' do + expect(subject.values[0]).to eq(post.id) + end + + it 'should have valid label' do + expect(subject.label).to eq("Resource equals") + end + end + + context 'type filter' do + let(:condition) do + search.conditions[1] + end + + it 'should have valid values' do + expect(subject.values[0]).to eq(post.class.to_s) + end + + it 'should have valid label' do + expect(subject.label).to eq("Resource type equals") + end + end + end + context 'search by has many association' do let(:resource) do namespace.register(Category) From 975c8ee053b460d936c0e5888b67f79683419717 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Fri, 23 Jun 2017 22:40:48 +0300 Subject: [PATCH 0622/3836] setup minimal ruby version for rubocop --- .rubocop.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 2f4821a4bcd..e19f968b9ed 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,7 +2,8 @@ AllCops: DisabledByDefault: true - + TargetRubyVersion: 2.2 + Exclude: - spec/rails/**/* - gemfiles/vendor/bundle/**/* From 97e24628c66fd4c9cc57d630a90833c437f3d72a Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sat, 24 Jun 2017 21:30:46 +0300 Subject: [PATCH 0623/3836] update pagination documentation doc for PR #3748 --- docs/3-index-pages.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index 99496ac6c5c..9558dff96c0 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -241,6 +241,14 @@ ActiveAdmin.register Post do end ``` +Or allow users to choose themselves using dropdown with values + +```ruby +ActiveAdmin.register Post do + config.per_page = [10, 50, 100] +end +``` + You can change it per request / action too: ```ruby From 882a7a1d3a064d68ffc3d0a0f7921be60057e891 Mon Sep 17 00:00:00 2001 From: Mauricio Pasquier Juan Date: Tue, 20 Jun 2017 03:36:58 -0300 Subject: [PATCH 0624/3836] Remove untranslated string from template --- lib/generators/active_admin/install/templates/admin_user.rb.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/active_admin/install/templates/admin_user.rb.erb b/lib/generators/active_admin/install/templates/admin_user.rb.erb index 3863739d448..9609db99af1 100644 --- a/lib/generators/active_admin/install/templates/admin_user.rb.erb +++ b/lib/generators/active_admin/install/templates/admin_user.rb.erb @@ -17,7 +17,7 @@ ActiveAdmin.register <%= @user_class %> do filter :created_at form do |f| - f.inputs "Admin Details" do + f.inputs do f.input :email f.input :password f.input :password_confirmation From 00a9846e46caf44631270001ed355f71e7e2b890 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Sun, 25 Jun 2017 10:22:38 +0300 Subject: [PATCH 0625/3836] update outdated doc for string filter [skip ci] --- docs/3-index-pages.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index 9558dff96c0..491d0a903cd 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -81,7 +81,8 @@ end Out of the box, Active Admin supports the following filter types: -* *:string* - A search field +* *:string* - A drop down for selecting "Contains", "Equals", "Starts with", + "Ends with" and an input for a value. * *:date_range* - A start and end date field with calendar inputs * *:numeric* - A drop down for selecting "Equal To", "Greater Than" or "Less Than" and an input for a value. From c6e1c22a6fbec35185aaa7d645d9d686d3174a71 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 26 Jun 2017 13:12:00 -0400 Subject: [PATCH 0626/3836] Remove task dependency that has been deleted --- tasks/local.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/local.rake b/tasks/local.rake index bd401e041e8..ee556c330c3 100644 --- a/tasks/local.rake +++ b/tasks/local.rake @@ -1,5 +1,5 @@ desc 'Runs a command agains the local sample application' -task local: :enforce_version do +task :local do Rake::Task['setup'].invoke(false, '.test-rails-apps', 'rails_template_with_data') From 49fdf19cee18a85fc16d2eede65d1a3f31470fe9 Mon Sep 17 00:00:00 2001 From: Benjamin Cavileer Date: Mon, 26 Jun 2017 20:09:51 -0400 Subject: [PATCH 0627/3836] Render meta tags before javascripts so they are available when scripts load. --- lib/active_admin/views/pages/base.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/active_admin/views/pages/base.rb b/lib/active_admin/views/pages/base.rb index db91ce94bce..fc02b8cd431 100644 --- a/lib/active_admin/views/pages/base.rb +++ b/lib/active_admin/views/pages/base.rb @@ -29,6 +29,10 @@ def build_active_admin_head text_node stylesheet_link_tag(style, options).html_safe end + active_admin_namespace.meta_tags.each do |name, content| + text_node(tag(:meta, name: name, content: content)) + end + active_admin_application.javascripts.each do |path| text_node(javascript_include_tag(path)) end @@ -37,10 +41,6 @@ def build_active_admin_head text_node(favicon_link_tag(active_admin_namespace.favicon)) end - active_admin_namespace.meta_tags.each do |name, content| - text_node(tag(:meta, name: name, content: content)) - end - text_node csrf_meta_tag end end From 3bd31a0aa9005cded78f73a005a5d5fba95ea47f Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 27 Jun 2017 11:28:53 -0400 Subject: [PATCH 0628/3836] Use Rails ~> 5.1.0 but focus on ActiveAdmin master Rearrange gems since the focus here is on ActiveAdmin, not Rails. --- lib/bug_report_templates/rails_5_master.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/bug_report_templates/rails_5_master.rb b/lib/bug_report_templates/rails_5_master.rb index 9220a7c482a..6870038800b 100644 --- a/lib/bug_report_templates/rails_5_master.rb +++ b/lib/bug_report_templates/rails_5_master.rb @@ -8,19 +8,21 @@ gemfile(true) do source 'https://rubygems.org' - gem 'rails', require: false - gem 'sqlite3', platform: :mri + # Use local changes or ActiveAdmin master. + if ENV['ACTIVE_ADMIN_PATH'] + gem 'activeadmin', path: ENV['ACTIVE_ADMIN_PATH'], require: false + else + gem 'activeadmin', github: 'activeadmin/activeadmin', require: false + end + + # Change Rails version if necessary. + gem 'rails', '~> 5.1.0' + gem 'sqlite3', platform: :mri gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter', branch: 'rails-5', platform: :jruby - - if ENV['ACTIVE_ADMIN_PATH'] - gem 'activeadmin', path: ENV['ACTIVE_ADMIN_PATH'], require: false - else - gem 'activeadmin', git: 'https://github.com/activeadmin/activeadmin', require: false - end end # prepare active_record database From 726868defcf3531fe7a3102f4656f03ef5e55eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 15:59:05 +0200 Subject: [PATCH 0629/3836] Normalize TODO notes For easier grepping, for example. --- .simplecov | 2 +- lib/active_admin/namespace.rb | 2 +- spec/support/active_admin_integration_spec_helper.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.simplecov b/.simplecov index 4db8e6a1a01..933a469585d 100644 --- a/.simplecov +++ b/.simplecov @@ -1,6 +1,6 @@ # frozen_string_literal: true -# @todo: Always run simplecov again once +# TODO: Always run simplecov again once # https://github.com/colszowka/simplecov/issues/404, # https://github.com/glebm/i18n-tasks/issues/221 are fixed if ENV['COVERAGE'] == 'true' diff --git a/lib/active_admin/namespace.rb b/lib/active_admin/namespace.rb index 73ae72c3688..5d3fd6e98d1 100644 --- a/lib/active_admin/namespace.rb +++ b/lib/active_admin/namespace.rb @@ -219,7 +219,7 @@ def register_module end end - # TODO replace `eval` with `Class.new` + # TODO: replace `eval` with `Class.new` def register_resource_controller(config) eval "class ::#{config.controller_name} < ActiveAdmin::ResourceController; end" config.controller.active_admin_config = config diff --git a/spec/support/active_admin_integration_spec_helper.rb b/spec/support/active_admin_integration_spec_helper.rb index 6ee6bc5fb7a..6abc931d605 100644 --- a/spec/support/active_admin_integration_spec_helper.rb +++ b/spec/support/active_admin_integration_spec_helper.rb @@ -62,7 +62,7 @@ def with_translation(translation) # If no translations have been loaded, any later calls to `I18n.t` will # cause the full translation hash to be loaded, possibly overwritting what # we've loaded via `store_translations`. We use this hack to prevent that. - # @todo Might not be necessary anymore once + # TODO: Might not be necessary anymore once # https://github.com/svenfuchs/i18n/pull/353 lands. I18n.backend.send(:init_translations) I18n.backend.store_translations I18n.locale, translation From 8fff78ebc036ddf2899b5c6323948c90acfe1e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 17 Jun 2017 15:59:59 +0200 Subject: [PATCH 0630/3836] Don't require simplecov when COVERAGE disabled --- .simplecov | 6 ++---- features/support/env.rb | 2 +- features/support/regular_env.rb | 6 ++++-- features/support/reload_env.rb | 6 ++++-- spec/spec_helper.rb | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.simplecov b/.simplecov index 933a469585d..33e78e55c4c 100644 --- a/.simplecov +++ b/.simplecov @@ -3,10 +3,8 @@ # TODO: Always run simplecov again once # https://github.com/colszowka/simplecov/issues/404, # https://github.com/glebm/i18n-tasks/issues/221 are fixed -if ENV['COVERAGE'] == 'true' - SimpleCov.start do - add_filter 'spec/rails/' - end +SimpleCov.start do + add_filter 'spec/rails/' end if ENV['CI'] == 'true' diff --git a/features/support/env.rb b/features/support/env.rb index 2aa371e453d..c217ed6746e 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -6,7 +6,7 @@ ENV['RAILS_ENV'] = 'test' -require 'simplecov' +require 'simplecov' if ENV["COVERAGE"] == "true" Dir["#{File.expand_path('../../step_definitions', __FILE__)}/*.rb"].each do |f| require f diff --git a/features/support/regular_env.rb b/features/support/regular_env.rb index 38969751fe9..dc2fce76492 100644 --- a/features/support/regular_env.rb +++ b/features/support/regular_env.rb @@ -1,5 +1,7 @@ -require 'simplecov' +if ENV["COVERAGE"] == "true" + require 'simplecov' -SimpleCov.command_name "regular features" + SimpleCov.command_name "regular features" +end require_relative 'env' diff --git a/features/support/reload_env.rb b/features/support/reload_env.rb index 9175d449518..f4a604e3ee7 100644 --- a/features/support/reload_env.rb +++ b/features/support/reload_env.rb @@ -1,5 +1,7 @@ -require 'simplecov' +if ENV["COVERAGE"] == "true" + require 'simplecov' -SimpleCov.command_name "reload features" + SimpleCov.command_name "reload features" +end require_relative 'env' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6d75bd08304..aac2cbd91f8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1 +1 @@ -require 'simplecov' +require 'simplecov' if ENV["COVERAGE"] == true From e9934fe0c32bec541286d2aff5b448f4e2ca1a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 27 Jun 2017 16:46:40 +0200 Subject: [PATCH 0631/3836] Do what JRuby does to overcome lack of entropy --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a35bddade4f..0d1880450ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,7 @@ gemfile: env: global: - JRUBY_OPTS="-J-Xmx1024m --dev --debug" + - JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom" - COVERAGE=true matrix: From 2f071a25fa2ad09d45636c49818230f303e46383 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 27 Jun 2017 11:30:47 -0400 Subject: [PATCH 0632/3836] Update app config/requires to match Rails bug template scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should stay consistent with how Rails sets up their action controller/view gem script template https://github.com/rails/rails/blob/master/guides/bug_report_templates/a ction_controller_gem.rb as we need that to properly test ActiveAdmin. Use preferred ActionDispatch::IntegrationTest for tests. This is best since it goes through the full Rails stack and we need that coverage for ActiveAdmin since the view is a big portion of it. Instead of YourModels, just create User model. Its weird having examples like that. I think its clearer having a real world example (Which the Rails templates do the same) so its easier to get started and see what’s going on as people are familiar with that. --- lib/bug_report_templates/rails_5_master.rb | 56 ++++++++++------------ 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/lib/bug_report_templates/rails_5_master.rb b/lib/bug_report_templates/rails_5_master.rb index 6870038800b..c0f09ae7125 100644 --- a/lib/bug_report_templates/rails_5_master.rb +++ b/lib/bug_report_templates/rails_5_master.rb @@ -25,7 +25,6 @@ platform: :jruby end -# prepare active_record database require 'active_record' ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') @@ -35,81 +34,74 @@ create_table :active_admin_comments, force: true do |_t| end - # Add your schema here - create_table :your_models, force: true do |t| - t.string :name + create_table :users, force: true do |t| + t.string :full_name end end -# prepare Rails app require 'action_controller/railtie' require 'action_view/railtie' require 'active_admin' -class ApplicationController < ActionController::Base -end - class TestApp < Rails::Application - config.root = File.dirname(__FILE__) - config.logger = Logger.new(STDOUT) - + config.root = __dir__ + config.session_store :cookie_store, key: "cookie_store_key" secrets.secret_token = 'secret_token' secrets.secret_key_base = 'secret_key_base' config.eager_load = false + config.logger = Logger.new($stdout) + Rails.logger = config.logger end -# create models -class YourModel < ActiveRecord::Base +class ApplicationController < ActionController::Base + include Rails.application.routes.url_helpers +end + +class User < ActiveRecord::Base end -# configure active_admin ActiveAdmin.setup do |config| - # Authentication disabled by default. Override if necessary + # Authentication disabled by default. Override if necessary. config.authentication_method = false config.current_user_method = false end -# initialize app Rails.application.initialize! -# register pages and resources ActiveAdmin.register_page 'Dashboard' do menu priority: 1, label: proc { I18n.t('active_admin.dashboard') } - content do 'Test Me' end end -ActiveAdmin.register YourModel do +ActiveAdmin.register User do end -# draw active_admin routes Rails.application.routes.draw do ActiveAdmin.routes(self) end -# prepare tests require 'minitest/autorun' require 'rack/test' +require 'rails/test_help' # Replace this with the code necessary to make your test fail. -class BugTest < Minitest::Test - include Rack::Test::Methods +class BugTest < ActionDispatch::IntegrationTest def test_admin_root_success? - get '/admin' - assert last_response.ok? - assert_match 'Test Me', last_response.body # has content - assert_match 'Your Models', last_response.body # has 'Your Models' in menu + get admin_root_url + assert_response :success + assert_match 'Test Me', response.body # has content + assert_match 'Users', response.body # has 'Your Models' in menu end - def test_admin_your_models - YourModel.create! name: 'John Doe' - get '/admin/your_models' - assert last_response.ok? - assert_match 'John Doe', last_response.body # has created row + def test_admin_users + User.create! full_name: 'John Doe' + get admin_users_url + assert_response :success + assert_match 'John Doe', response.body # has created row end private From a323b27ff8034a4371cb3c7bb8df57f37adbd7f3 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 27 Jun 2017 11:42:26 -0400 Subject: [PATCH 0633/3836] Rename to active_admin_master as that is what the report is for MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The report isn’t for Rails 5 master but for ActiveAdmin. Seeing this for the first time I can see someone thinking it doesn’t apply to them because they aren’t thinking they are running into a Rails issue, but an ActiveAdmin issue. Now we can start requiring users to use this to replicate bugs. --- CONTRIBUTING.md | 10 +++++----- .../{rails_5_master.rb => active_admin_master.rb} | 0 spec/bug_report_templates_spec.rb | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) rename lib/bug_report_templates/{rails_5_master.rb => active_admin_master.rb} (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 259bd2c139b..360d7e70969 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,14 +61,14 @@ rm -rf spec/rails && bundle update * **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/activeadmin/activeadmin/issues). -* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/activeadmin/activeadmin/issues/new). -Be sure to include a **title and clear description**, as much relevant information as possible, +* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/activeadmin/activeadmin/issues/new). +Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. -* If possible, use the relevant bug report templates to create the issue. -Simply copy the content of the appropriate template into a .rb file, make the necessary changes to demonstrate the issue, +* If possible, use the relevant bug report templates to create the issue. +Simply copy the content of the appropriate template into a .rb file, make the necessary changes to demonstrate the issue, and **paste the content into the issue description**: - * [**Rails 5** issues](https://github.com/activeadmin/activeadmin/blob/master/lib/bug_report_templates/rails_5_master.rb) + * [**ActiveAdmin** master issues](https://github.com/activeadmin/activeadmin/blob/master/lib/bug_report_templates/active_admin_master.rb) ### 5. Implement your fix or feature diff --git a/lib/bug_report_templates/rails_5_master.rb b/lib/bug_report_templates/active_admin_master.rb similarity index 100% rename from lib/bug_report_templates/rails_5_master.rb rename to lib/bug_report_templates/active_admin_master.rb diff --git a/spec/bug_report_templates_spec.rb b/spec/bug_report_templates_spec.rb index 25d1d44e4f5..2b3fa2cff5b 100644 --- a/spec/bug_report_templates_spec.rb +++ b/spec/bug_report_templates_spec.rb @@ -15,8 +15,8 @@ let(:active_admin_root) { File.expand_path('../..', __FILE__) } let(:chdir_path) { File.join(active_admin_root, 'lib', 'bug_report_templates') } - context 'when runs rails_5_master.rb' do - let(:template_path) { 'rails_5_master.rb' } + context 'when runs active_admin_master.rb' do + let(:template_path) { 'active_admin_master.rb' } it 'passes' do expect(subject).to be_truthy From bb53092aaf5c63ecfcc84c5403141943c8e9908b Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 27 Jun 2017 11:57:06 -0400 Subject: [PATCH 0634/3836] Link to issues with search all enabled By default search is only for open issues but by setting an empty query we can change that to be all issues as desired. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 360d7e70969..68872330da0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,7 +59,7 @@ rm -rf spec/rails && bundle update #### 4. Did you find a bug? -* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/activeadmin/activeadmin/issues). +* **Ensure the bug was not already reported** by [searching all issues](https://github.com/activeadmin/activeadmin/issues?q=). * If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/activeadmin/activeadmin/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, From e06fe81332fa76c7d18d33e31d536930f9564a4d Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 27 Jun 2017 11:59:26 -0400 Subject: [PATCH 0635/3836] Streamline content so its readable in preview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Painful to use comments here. Best to remove it like in other repo issue templates so it renders nicely in Preview with links enabled. Focus on directing users to the contributing guidelines so that way they provide us with an executable script. These are incredibly useful and can be coded faster than a sample app. Wish I knew we had this setup before as I’ve submitted Rails issues with their script template and its great. --- .github/ISSUE_TEMPLATE.md | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 1ca99b627ef..fd93fe8d8a1 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,26 +1,15 @@ - +The issue tracker is only for bugs and feature requests. If you need general help please post to [StackOverflow](http://stackoverflow.com/questions/tagged/activeadmin). ### Expected behavior - +What do you think should happen? ### Actual behavior - +What actually happens? ### How to reproduce - +Your best chance of getting this bug looked at quickly is to provide an **executable test case** demonstrating the expected behavior that is not occurring. [Please follow the guidelines for creating a bug report](https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md#4-did-you-find-a-bug). From 9c2da9efc8eca7130971444abc926a59447f3ef2 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 28 Jun 2017 09:52:28 +0300 Subject: [PATCH 0636/3836] trigger separate js event for each batch action --- CHANGELOG.md | 2 ++ .../javascripts/active_admin/lib/batch_actions.js.coffee | 4 ++-- .../javascripts/active_admin/lib/modal_dialog.js.coffee | 7 ++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87737740a33..bfe42cc2202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ * Allow AA scopes to return paginated collections [#4996][] by [@Fivell][] * Added `scopes_show_count` configuration to setup show_count attribute for scopes globally [#4950][] by [@Fivell][] * Allow custom panel title given with `attributes_table` [#4940][] by [@ajw725][] +* Added unique js events for each particular batch action [#5040][] by [@Fivell][] + ## 1.0.0 [☰](https://github.com/activeadmin/activeadmin/compare/v0.6.3...master) diff --git a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee index 90684674c33..bba6442c1d9 100644 --- a/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee +++ b/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee @@ -6,8 +6,8 @@ $(document).on 'ready page:load turbolinks:load', -> $('.batch_actions_selector li a').click (e)-> e.stopPropagation() # prevent Rails UJS click event e.preventDefault() - if message = $(@).data 'confirm' - ActiveAdmin.modal_dialog message, $(@).data('inputs'), (inputs)=> + if $(@).data 'confirm' + ActiveAdmin.modal_dialog $(@), (inputs)=> $(@).trigger 'confirm:complete', inputs else $(@).trigger 'confirm:complete' diff --git a/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee b/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee index ae697ba61dd..26e79b24ea2 100644 --- a/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee +++ b/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee @@ -1,4 +1,7 @@ -ActiveAdmin.modal_dialog = (message, inputs, callback)-> +ActiveAdmin.modal_dialog = (batch_action, callback)-> + message = batch_action.data 'confirm' + inputs = batch_action.data 'inputs' + action = batch_action.data 'action' html = """
        """ for name, type of inputs if /^(datepicker|checkbox|text|number)$/.test type @@ -31,11 +34,13 @@ ActiveAdmin.modal_dialog = (message, inputs, callback)-> form = $(html).appendTo('body') $('body').trigger 'modal_dialog:before_open', [form] + $('body').trigger "modal_dialog:#{action}:before_open", [form] form.dialog modal: true open: (event, ui) -> $('body').trigger 'modal_dialog:after_open', [form] + $('body').trigger "modal_dialog:#{action}:after_open", [form] dialogClass: 'active_admin_dialog' buttons: OK: -> From 22408a2e057d21049a90f12c0d5cb6089bbadd15 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 26 Jun 2017 13:31:21 -0400 Subject: [PATCH 0637/3836] Replace sass-rails with just sass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We shouldn’t have to require sass-rails but like other gems (e.g. foundation-rails) that use sass heavily, they just have sass a dependency no require statement in ruby necessary. This also helps with issues like #5031 where users can stick with Rails default of sass-rails or use sassc-rails. --- activeadmin.gemspec | 2 +- lib/active_admin.rb | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index 43fe3b332ba..8f8a3d9f208 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -29,6 +29,6 @@ Gem::Specification.new do |s| s.add_dependency 'kaminari', '>= 0.15', '< 2.0' s.add_dependency 'railties', '>= 4.2', '< 5.2' s.add_dependency 'ransack', '~> 1.3' - s.add_dependency 'sass-rails' + s.add_dependency 'sass' s.add_dependency 'sprockets', '< 4.1' end diff --git a/lib/active_admin.rb b/lib/active_admin.rb index 1d21bc4efc5..ed02d6b824b 100644 --- a/lib/active_admin.rb +++ b/lib/active_admin.rb @@ -7,7 +7,6 @@ require 'kaminari' require 'formtastic' require 'formtastic_i18n' -require 'sass-rails' require 'inherited_resources' require 'jquery-rails' require 'jquery-ui-rails' From 04fc4d8ba4b516bc8a6fdcbdea8ce163377938e6 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 26 Jun 2017 14:12:25 -0400 Subject: [PATCH 0638/3836] Rename with scss extension for importing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing to worry here since this will work as is but despite not containing any SASS, we need this to be named with a scss extension to successfully import. We don’t lose anything with this change so its safe. --- .../stylesheets/active_admin/{_normalize.css => _normalize.scss} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename vendor/assets/stylesheets/active_admin/{_normalize.css => _normalize.scss} (100%) diff --git a/vendor/assets/stylesheets/active_admin/_normalize.css b/vendor/assets/stylesheets/active_admin/_normalize.scss similarity index 100% rename from vendor/assets/stylesheets/active_admin/_normalize.css rename to vendor/assets/stylesheets/active_admin/_normalize.scss From 519a7877410739d1526a3f78046434659497f8f7 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 26 Jun 2017 14:14:22 -0400 Subject: [PATCH 0639/3836] Include sass-rails as its a default for Rails Gemfile This worked previously since we were required sass-rails but Rails has this by default so moving this here and our test will pass. This is fine since the default for Rails is to include sass-rails and we have a dependency on sass. --- lib/bug_report_templates/active_admin_master.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/bug_report_templates/active_admin_master.rb b/lib/bug_report_templates/active_admin_master.rb index c0f09ae7125..0a3e4c72d12 100644 --- a/lib/bug_report_templates/active_admin_master.rb +++ b/lib/bug_report_templates/active_admin_master.rb @@ -18,6 +18,7 @@ # Change Rails version if necessary. gem 'rails', '~> 5.1.0' + gem 'sass-rails' gem 'sqlite3', platform: :mri gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter', From dab92857be9ce728558a76c235950c037c9b0158 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 26 Jun 2017 18:50:13 -0400 Subject: [PATCH 0640/3836] Add changelog notice --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfe42cc2202..ae5ac4e20f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Removals * Ruby 2.1 support has been dropped [#5002][] by [@deivid-rodriguez][] +* Replaced `sass-rails` with `sass` dependency [#5037][] by [@javierjulio][] ### Deprecations From 4a95a528a2515471ddd345cdb62bf3d4df63b7b8 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Wed, 28 Jun 2017 15:13:12 -0400 Subject: [PATCH 0641/3836] Set sass to '~> 3.1' --- activeadmin.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index 8f8a3d9f208..dd7c2e8ced5 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -29,6 +29,6 @@ Gem::Specification.new do |s| s.add_dependency 'kaminari', '>= 0.15', '< 2.0' s.add_dependency 'railties', '>= 4.2', '< 5.2' s.add_dependency 'ransack', '~> 1.3' - s.add_dependency 'sass' + s.add_dependency 'sass', '~> 3.1' s.add_dependency 'sprockets', '< 4.1' end From 7a1f55c7c1460260a9a55a46fb66f163dec5b27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 27 Jun 2017 20:26:22 +0200 Subject: [PATCH 0642/3836] Fix markdownlint CI status And fix one issue that had sneaked in. --- docs/3-index-pages.md | 2 +- tasks/lint.rake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/3-index-pages.md b/docs/3-index-pages.md index 491d0a903cd..a39def2287a 100644 --- a/docs/3-index-pages.md +++ b/docs/3-index-pages.md @@ -81,7 +81,7 @@ end Out of the box, Active Admin supports the following filter types: -* *:string* - A drop down for selecting "Contains", "Equals", "Starts with", +* *:string* - A drop down for selecting "Contains", "Equals", "Starts with", "Ends with" and an input for a value. * *:date_range* - A start and end date field with calendar inputs * *:numeric* - A drop down for selecting "Equal To", "Greater Than" or "Less diff --git a/tasks/lint.rake b/tasks/lint.rake index 8a02cd689d8..bdaeaefe260 100644 --- a/tasks/lint.rake +++ b/tasks/lint.rake @@ -9,6 +9,6 @@ namespace :lint do desc "Checks markdown code style with Markdownlint" task :mdl do puts "Running mdl..." - system("mdl docs/*.md") + abort unless system("mdl docs/*.md") end end From bdc8eb875eebecb6a8bf15ca94b12faef6bf69c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 28 Jun 2017 12:41:53 +0200 Subject: [PATCH 0643/3836] Lint more md files and fix more issues Not sure why these issues went undetected before. --- .github/ISSUE_TEMPLATE.md | 9 +++++++-- .mdlrc | 1 + CONTRIBUTING.md | 27 +++++++++++++++------------ config/mdl_style.rb | 7 +++++++ docs/0-installation.md | 10 ++++------ docs/14-gotchas.md | 2 +- docs/2-resource-customization.md | 2 +- tasks/lint.rake | 9 ++++++++- 8 files changed, 44 insertions(+), 23 deletions(-) create mode 100644 .mdlrc create mode 100644 config/mdl_style.rb diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index fd93fe8d8a1..0b8c67d8019 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,6 +1,8 @@ [Please follow the guidelines for creating a bug report](https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md#4-did-you-find-a-bug). -The issue tracker is only for bugs and feature requests. If you need general help please post to [StackOverflow](http://stackoverflow.com/questions/tagged/activeadmin). +The issue tracker is only for bugs and feature requests. If you need general +help please post to +[StackOverflow](http://stackoverflow.com/questions/tagged/activeadmin). ### Expected behavior @@ -12,4 +14,7 @@ What actually happens? ### How to reproduce -Your best chance of getting this bug looked at quickly is to provide an **executable test case** demonstrating the expected behavior that is not occurring. [Please follow the guidelines for creating a bug report](https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md#4-did-you-find-a-bug). +Your best chance of getting this bug looked at quickly is to provide an +**executable test case** demonstrating the expected behavior that is not +occurring. [Please follow the guidelines for creating a bug +report](https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md#4-did-you-find-a-bug). diff --git a/.mdlrc b/.mdlrc new file mode 100644 index 00000000000..3c6de4a3a39 --- /dev/null +++ b/.mdlrc @@ -0,0 +1 @@ +style "config/mdl_style.rb" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68872330da0..637b52a1eba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,18 +57,23 @@ environment: rm -rf spec/rails && bundle update ``` -#### 4. Did you find a bug? +### 4. Did you find a bug? -* **Ensure the bug was not already reported** by [searching all issues](https://github.com/activeadmin/activeadmin/issues?q=). +* **Ensure the bug was not already reported** by [searching all + issues](https://github.com/activeadmin/activeadmin/issues?q=). -* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/activeadmin/activeadmin/issues/new). -Be sure to include a **title and clear description**, as much relevant information as possible, -and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. +* If you're unable to find an open issue addressing the problem, [open a new + one](https://github.com/activeadmin/activeadmin/issues/new). Be sure to + include a **title and clear description**, as much relevant information as + possible, and a **code sample** or an **executable test case** demonstrating + the expected behavior that is not occurring. * If possible, use the relevant bug report templates to create the issue. -Simply copy the content of the appropriate template into a .rb file, make the necessary changes to demonstrate the issue, -and **paste the content into the issue description**: - * [**ActiveAdmin** master issues](https://github.com/activeadmin/activeadmin/blob/master/lib/bug_report_templates/active_admin_master.rb) + Simply copy the content of the appropriate template into a .rb file, make the + necessary changes to demonstrate the issue, and **paste the content into the + issue description**: + * [**ActiveAdmin** master + issues](https://github.com/activeadmin/activeadmin/blob/master/lib/bug_report_templates/active_admin_master.rb) ### 5. Implement your fix or feature @@ -92,10 +97,8 @@ in the `.test-rails-apps` folder. You should now be able to open in your browser. You can log in using: -``` -User: admin@example.com -Password: password -``` +*User*: admin@example.com +*Password*: password If you need to perform any other commands on the test application, just pass them to the `local` rake task. For example, to boot the rails console: diff --git a/config/mdl_style.rb b/config/mdl_style.rb new file mode 100644 index 00000000000..90887628bdc --- /dev/null +++ b/config/mdl_style.rb @@ -0,0 +1,7 @@ +all + +exclude_rule "MD002" + +rule "MD026", punctuation: ".,;:!" + +exclude_rule "MD041" diff --git a/docs/0-installation.md b/docs/0-installation.md index 88aa27263e2..4d8f42a057f 100644 --- a/docs/0-installation.md +++ b/docs/0-installation.md @@ -43,12 +43,10 @@ After installing the gem, you need to run the generator. Here are your options: The generator adds these core files, among others: -``` -app/admin/dashboard.rb -app/assets/javascripts/active_admin.js.coffee -app/assets/stylesheets/active_admin.scss -config/initializers/active_admin.rb -``` +* `app/admin/dashboard.rb` +* `app/assets/javascripts/active_admin.js.coffee` +* `app/assets/stylesheets/active_admin.scss` +* `config/initializers/active_admin.rb` Now, migrate and seed your database before starting the server: diff --git a/docs/14-gotchas.md b/docs/14-gotchas.md index 294334e866e..071880f87c3 100644 --- a/docs/14-gotchas.md +++ b/docs/14-gotchas.md @@ -116,7 +116,7 @@ under Rails 5 as it replaces the default scaffold generator. The solution is to configure the default controller in `config/application.rb` as outlined in [activeadmin/inherited_resources#195](https://github.com/activeadmin/inherited_resources/issues/195) -``` +```ruby module SampleApp class Application < Rails::Application ... diff --git a/docs/2-resource-customization.md b/docs/2-resource-customization.md index fb358b224a1..f290aa2acd0 100644 --- a/docs/2-resource-customization.md +++ b/docs/2-resource-customization.md @@ -112,7 +112,7 @@ new, edit, and destroy by providing a resource specific translation. For example, to change 'New Offer' to 'Make an Offer' add the following in config/locales/[en].yml: -``` +```yaml en: active_admin: resources: diff --git a/tasks/lint.rake b/tasks/lint.rake index bdaeaefe260..f21e488217b 100644 --- a/tasks/lint.rake +++ b/tasks/lint.rake @@ -9,6 +9,13 @@ namespace :lint do desc "Checks markdown code style with Markdownlint" task :mdl do puts "Running mdl..." - abort unless system("mdl docs/*.md") + + targets = [ + *Dir.glob("docs/*.md"), + "CONTRIBUTING.md", + ".github/ISSUE_TEMPLATE.md" + ] + + abort unless system("mdl", *targets) end end From 4535da8b58cf7a8f73b9f5933059374f0f7dd2e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 20:02:16 -0300 Subject: [PATCH 0644/3836] Remove warnings from generated docs I'll be enforcing this automatically. --- docs/3-index-pages/index-as-block.md | 5 ----- docs/3-index-pages/index-as-blog.md | 5 ----- docs/3-index-pages/index-as-grid.md | 5 ----- docs/3-index-pages/index-as-table.md | 5 ----- tasks/docs.rake | 11 +---------- 5 files changed, 1 insertion(+), 30 deletions(-) diff --git a/docs/3-index-pages/index-as-block.md b/docs/3-index-pages/index-as-block.md index aaf4010bc36..db5c32c1252 100644 --- a/docs/3-index-pages/index-as-block.md +++ b/docs/3-index-pages/index-as-block.md @@ -1,11 +1,6 @@ --- redirect_from: /docs/3-index-pages/index-as-block.html --- - # Index as a Block diff --git a/docs/3-index-pages/index-as-blog.md b/docs/3-index-pages/index-as-blog.md index ca832af541f..9d1e3412f31 100644 --- a/docs/3-index-pages/index-as-blog.md +++ b/docs/3-index-pages/index-as-blog.md @@ -1,11 +1,6 @@ --- redirect_from: /docs/3-index-pages/index-as-blog.html --- - # Index as Blog diff --git a/docs/3-index-pages/index-as-grid.md b/docs/3-index-pages/index-as-grid.md index 81553ff8925..c4e5f92ae73 100644 --- a/docs/3-index-pages/index-as-grid.md +++ b/docs/3-index-pages/index-as-grid.md @@ -1,11 +1,6 @@ --- redirect_from: /docs/3-index-pages/index-as-grid.html --- - # Index as a Grid diff --git a/docs/3-index-pages/index-as-table.md b/docs/3-index-pages/index-as-table.md index 438348eb7a0..ffe3fd2a98d 100644 --- a/docs/3-index-pages/index-as-table.md +++ b/docs/3-index-pages/index-as-table.md @@ -1,11 +1,6 @@ --- redirect_from: /docs/3-index-pages/index-as-table.html --- - # Index as a Table diff --git a/tasks/docs.rake b/tasks/docs.rake index cbfc62055a3..786634557aa 100644 --- a/tasks/docs.rake +++ b/tasks/docs.rake @@ -1,14 +1,5 @@ namespace :docs do - AUTOGEN_WARNING = <<-EOD - - -EOD - def filename_from_module(mod) mod.name.to_s.underscore.tr('_', '-') end @@ -16,7 +7,7 @@ EOD def write_docstrings_to(path, mods) mods.each do |mod| File.open("#{path}/#{filename_from_module(mod)}.md", 'w+') do |f| - f << AUTOGEN_WARNING + mod.docstring + "\n" + f << mod.docstring + "\n" end end end From b10409e6e0ae05344b99d5429ec74fd07a69ee94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 20:02:49 -0300 Subject: [PATCH 0645/3836] Write jekyll redirect to generated docs --- tasks/docs.rake | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tasks/docs.rake b/tasks/docs.rake index 786634557aa..24994dd1102 100644 --- a/tasks/docs.rake +++ b/tasks/docs.rake @@ -1,13 +1,24 @@ namespace :docs do + def jekyll_redirect_string(filename) + <<-EOD.strip_heredoc + --- + redirect_from: /docs/3-index-pages/#{filename} + --- + + EOD + end + def filename_from_module(mod) mod.name.to_s.underscore.tr('_', '-') end def write_docstrings_to(path, mods) mods.each do |mod| - File.open("#{path}/#{filename_from_module(mod)}.md", 'w+') do |f| - f << mod.docstring + "\n" + filename = filename_from_module(mod) + + File.open("#{path}/#{filename}.md", 'w+') do |f| + f << jekyll_redirect_string("#{filename}.html") + mod.docstring + "\n" end end end From e3be2ca3d418b1e260c64404f5760860b836537b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 20:10:30 -0300 Subject: [PATCH 0646/3836] Make sure docs are generated before building them --- tasks/docs.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/docs.rake b/tasks/docs.rake index 24994dd1102..8c2a01d20ee 100644 --- a/tasks/docs.rake +++ b/tasks/docs.rake @@ -24,7 +24,7 @@ namespace :docs do end desc "Update docs in the docs folder" - task :build do + task build: :yard do require 'yard' require 'active_support/all' From 55f1f712147cc0796ac1d8e6f926332c139f39b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 20:10:47 -0300 Subject: [PATCH 0647/3836] Remove dummy comment Just to normalize with the other analogous files which don't have it. --- lib/active_admin/views/index_as_table.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_admin/views/index_as_table.rb b/lib/active_admin/views/index_as_table.rb index 01323833c30..a5955ae5e0c 100644 --- a/lib/active_admin/views/index_as_table.rb +++ b/lib/active_admin/views/index_as_table.rb @@ -368,6 +368,6 @@ def item *args end end # IndexTableFor - end # IndexAsTable + end end end From 3b6d33e068db1bbdeef382d1966ccf8592e02de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 20:28:03 -0300 Subject: [PATCH 0648/3836] Make automatic docs are always in sync --- .travis.yml | 1 + tasks/docs.rake | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0d1880450ce..b9d9b0b3d33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ before_install: script: - bundle exec rake + - bundle exec rake docs:build rvm: - jruby-9.1.12.0 diff --git a/tasks/docs.rake b/tasks/docs.rake index 8c2a01d20ee..106a28f5825 100644 --- a/tasks/docs.rake +++ b/tasks/docs.rake @@ -23,6 +23,21 @@ namespace :docs do end end + def docs_syncronized? + # Do not print diff and yield whether exit code was zero + sh('git diff --quiet docs/3-index-pages') do |outcome, _| + return if outcome + + # Output diff before raising error + sh('git diff docs/3-index-pages') + + raise <<-MSG.strip_heredoc + The docs/3-index-pages directory is out of sync. + Run rake generate_cops_documentation and commit the results. + MSG + end + end + desc "Update docs in the docs folder" task build: :yard do require 'yard' @@ -34,6 +49,8 @@ namespace :docs do # Index Types index_types = views.children.select{|obj| obj.name.to_s =~ /^IndexAs/ } write_docstrings_to "docs/3-index-pages", index_types + + docs_syncronized? if ENV["CI"] end end From 9c0a02fc59eaac7b887a031058f0df5428a145ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 21:26:15 -0300 Subject: [PATCH 0649/3836] Move doc gems out of Gemfile groups So they can run in CI. --- Gemfile | 10 +++++----- tasks/yard.rake | 12 +++++------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index 0d8b3fbb99e..2de3a2d055c 100644 --- a/Gemfile +++ b/Gemfile @@ -25,6 +25,11 @@ gem 'mdl', '0.4.0' # Translations gem 'i18n-tasks' +# Documentation +gem 'yard' # Documentation generator +gem 'redcarpet', platforms: :mri # Markdown implementation (for yard) +gem 'kramdown', platforms: :jruby # Markdown implementation (for yard) + group :development do # Debugging gem 'better_errors' # Web UI to debug exceptions. Go to /__better_errors to access the latest one @@ -33,11 +38,6 @@ group :development do # Performance gem 'rack-mini-profiler' # Inline app profiler. See ?pp=help for options. - - # Documentation - gem 'yard' # Documentation generator - gem 'redcarpet', platforms: :mri # Markdown implementation (for yard) - gem 'kramdown', platforms: :jruby # Markdown implementation (for yard) end group :test do diff --git a/tasks/yard.rake b/tasks/yard.rake index 122e603db08..18f6473e509 100644 --- a/tasks/yard.rake +++ b/tasks/yard.rake @@ -1,9 +1,7 @@ -if Gem.loaded_specs['yard'] - require 'yard' - require 'yard/rake/yardoc_task' +require 'yard' +require 'yard/rake/yardoc_task' - YARD::Rake::YardocTask.new do |t| - t.after = ->{ Rake::Task['docs:build'].invoke } - t.files = ['lib/**/*.rb'] - end +YARD::Rake::YardocTask.new do |t| + t.after = ->{ Rake::Task['docs:build'].invoke } + t.files = ['lib/**/*.rb'] end From 33abf6715358dc8c61f67c1da781ed0a60b71fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 21:27:47 -0300 Subject: [PATCH 0650/3836] Remove unnecessary configuration We are already configuring yard as a prerequisite for doc generation. So we don't need this. --- tasks/yard.rake | 1 - 1 file changed, 1 deletion(-) diff --git a/tasks/yard.rake b/tasks/yard.rake index 18f6473e509..71333849d7c 100644 --- a/tasks/yard.rake +++ b/tasks/yard.rake @@ -2,6 +2,5 @@ require 'yard' require 'yard/rake/yardoc_task' YARD::Rake::YardocTask.new do |t| - t.after = ->{ Rake::Task['docs:build'].invoke } t.files = ['lib/**/*.rb'] end From 1caeb9d91d4f19c741e6e581cce39e41b8dd3638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 21:30:16 -0300 Subject: [PATCH 0651/3836] Merge docs.rake and yard.rake Since they are part of the same thing. --- tasks/docs.rake | 7 +++++++ tasks/yard.rake | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 tasks/yard.rake diff --git a/tasks/docs.rake b/tasks/docs.rake index 106a28f5825..05864449ddb 100644 --- a/tasks/docs.rake +++ b/tasks/docs.rake @@ -1,5 +1,12 @@ +require 'yard' +require 'yard/rake/yardoc_task' + namespace :docs do + YARD::Rake::YardocTask.new do |t| + t.files = ['lib/**/*.rb'] + end + def jekyll_redirect_string(filename) <<-EOD.strip_heredoc --- diff --git a/tasks/yard.rake b/tasks/yard.rake deleted file mode 100644 index 71333849d7c..00000000000 --- a/tasks/yard.rake +++ /dev/null @@ -1,6 +0,0 @@ -require 'yard' -require 'yard/rake/yardoc_task' - -YARD::Rake::YardocTask.new do |t| - t.files = ['lib/**/*.rb'] -end From de2b182986bdce963aafe50db8801acf68ed75ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 24 Jun 2017 23:30:55 +0200 Subject: [PATCH 0652/3836] No need to pass --exclude Since we are passing files explicitly. --- .yardopts | 1 - 1 file changed, 1 deletion(-) diff --git a/.yardopts b/.yardopts index 20705ef90d1..fe65f43518e 100644 --- a/.yardopts +++ b/.yardopts @@ -1,7 +1,6 @@ lib/**/*.rb --protected --no-private ---exclude (features|lib\/generators\/active_admin\/.*\/templates) - README.md CHANGELOG.md From c11ccdfcc725a6af8f3ff1ca87b79031a74655fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 24 Jun 2017 23:37:35 +0200 Subject: [PATCH 0653/3836] Fix some yard warnings --- lib/active_admin/filters/active.rb | 6 ++++-- lib/active_admin/filters/active_filter.rb | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/active_admin/filters/active.rb b/lib/active_admin/filters/active.rb index 8775c5578ee..0e0b6d25d35 100644 --- a/lib/active_admin/filters/active.rb +++ b/lib/active_admin/filters/active.rb @@ -8,8 +8,10 @@ class Active # Instantiate a `Active` object containing collection of current active filters - # @param [ActiveAdmin::Resource] current resource - # @param [Ransack::Search] search object, see ActiveAdmin::ResourceController::DataAcces#apply_filtering + # @param resource [ActiveAdmin::Resource] current resource + # @param search [Ransack::Search] search object + # + # @see ActiveAdmin::ResourceController::DataAcces#apply_filtering def initialize(resource, search) @resource = resource @filters = build_filters(search.conditions) diff --git a/lib/active_admin/filters/active_filter.rb b/lib/active_admin/filters/active_filter.rb index 8d3c17003f8..d634a4a182a 100644 --- a/lib/active_admin/filters/active_filter.rb +++ b/lib/active_admin/filters/active_filter.rb @@ -8,8 +8,8 @@ class ActiveFilter # Instantiate a `ActiveFilter` # - # @param [ActiveAdmin::Resource] current resource - # @param [Ransack::Nodes::Condition] applied ransack condition + # @param resource [ActiveAdmin::Resource] current resource + # @param condition [Ransack::Nodes::Condition] applied ransack condition def initialize(resource, condition) @resource = resource @condition = condition From 52459b907a818353ece952602d7996ec8d198ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sat, 24 Jun 2017 23:39:25 +0200 Subject: [PATCH 0654/3836] Speed up doc generation We don't want to generate all yard documentation, just the .yardoc database. --- tasks/docs.rake | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/docs.rake b/tasks/docs.rake index 05864449ddb..eba44834cfd 100644 --- a/tasks/docs.rake +++ b/tasks/docs.rake @@ -5,6 +5,7 @@ namespace :docs do YARD::Rake::YardocTask.new do |t| t.files = ['lib/**/*.rb'] + t.options = ['--no-output'] end def jekyll_redirect_string(filename) From e6de8286bf273b2717cf318b6d861c404d4d82c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 28 Jun 2017 23:43:08 +0200 Subject: [PATCH 0655/3836] Add missing doc files to mdl lint check --- tasks/lint.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/lint.rake b/tasks/lint.rake index f21e488217b..693d557c7c4 100644 --- a/tasks/lint.rake +++ b/tasks/lint.rake @@ -11,7 +11,7 @@ namespace :lint do puts "Running mdl..." targets = [ - *Dir.glob("docs/*.md"), + *Dir.glob("docs/**/*.md"), "CONTRIBUTING.md", ".github/ISSUE_TEMPLATE.md" ] From 62efd76b09536b74f0aa0d4b648f0e80dfb351fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 28 Jun 2017 23:44:28 +0200 Subject: [PATCH 0656/3836] Exclude line length checks from mdl Since some of the docs are generated from ruby documentation, and we are not enforcing a minimum line length for ruby files, I think it's better to disable this since it's likely to get in the middle. --- config/mdl_style.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/mdl_style.rb b/config/mdl_style.rb index 90887628bdc..d03ff1cf1d6 100644 --- a/config/mdl_style.rb +++ b/config/mdl_style.rb @@ -2,6 +2,8 @@ exclude_rule "MD002" +exclude_rule "MD013" + rule "MD026", punctuation: ".,;:!" exclude_rule "MD041" From 76e1f35b7b15ab773a4bb4f50d0ee7c8afd1be9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 28 Jun 2017 23:47:38 +0200 Subject: [PATCH 0657/3836] Use rule aliases instead of cryptic names --- config/mdl_style.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/mdl_style.rb b/config/mdl_style.rb index d03ff1cf1d6..dd1c9f2149e 100644 --- a/config/mdl_style.rb +++ b/config/mdl_style.rb @@ -1,9 +1,9 @@ all -exclude_rule "MD002" +exclude_rule "first-header-h1" -exclude_rule "MD013" +exclude_rule "line-length" -rule "MD026", punctuation: ".,;:!" +rule "no-trailing-punctuation", punctuation: ".,;:!" -exclude_rule "MD041" +exclude_rule "first-line-h1" From aa5f9f3c7b1b3bf430b1154327f06f4fcee809ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 4 Jun 2017 20:09:49 -0300 Subject: [PATCH 0658/3836] Sync docs --- docs/3-index-pages/index-as-table.md | 37 +++++++++--------------- lib/active_admin/views/index_as_table.rb | 18 ++++++++++++ 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/docs/3-index-pages/index-as-table.md b/docs/3-index-pages/index-as-table.md index ffe3fd2a98d..a6e0577bfe1 100644 --- a/docs/3-index-pages/index-as-table.md +++ b/docs/3-index-pages/index-as-table.md @@ -4,9 +4,8 @@ redirect_from: /docs/3-index-pages/index-as-table.html # Index as a Table -By default, the index page is a table with each of the models content columns -and links to show, edit and delete the object. There are many ways to customize -what gets +By default, the index page is a table with each of the models content columns and links to +show, edit and delete the object. There are many ways to customize what gets displayed. ## Defining Columns @@ -40,12 +39,10 @@ end ``` Sometimes that just isn't enough and you need to write some view-specific code. -For example, say we wanted a "Title" column that links to the posts admin -screen. +For example, say we wanted a "Title" column that links to the posts admin screen. -`column` accepts a block that will be rendered for each of the objects in the -collection. The block is called once for each resource, which is passed as an -argument to the block. +`column` accepts a block that will be rendered for each of the objects in the collection. +The block is called once for each resource, which is passed as an argument to the block. ```ruby index do @@ -87,8 +84,6 @@ index do column :title actions defaults: false do |post| item "View", admin_post_path(post) - item "Edit", edit_admin_post_path(post) - item "Delete", admin_post_path(post), method: :delete end end ``` @@ -116,8 +111,7 @@ index do end ``` -In addition, you can insert the position of the row in the greater collection by -using the index_column special command: +In addition, you can insert the position of the row in the greater collection by using the index_column special command: ```ruby index do @@ -127,8 +121,7 @@ index do end ``` -index_column take an optional offset parameter to allow a developer to set the -starting number for the index (default is 1). +index_column take an optional offset parameter to allow a developer to set the starting number for the index (default is 1). ## Sorting @@ -136,12 +129,11 @@ When a column is generated from an Active Record attribute, the table is sortable by default. If you are creating a custom column, you may need to give Active Admin a hint for how to sort the table. -If a column is defined using a block, you must pass the key to turn on sorting. -The key is the attribute which gets used to sort objects using Active Record. +If a column is defined using a block, you must pass the key to turn on sorting. The key +is the attribute which gets used to sort objects using Active Record. -By default, this is the column on the resource's table that the attribute -corresponds to. Otherwise, any attribute that the resource collection responds -to can be used. +By default, this is the column on the resource's table that the attribute corresponds to. +Otherwise, any attribute that the resource collection responds to can be used. ```ruby index do @@ -170,8 +162,7 @@ end ## Custom sorting -It is also possible to use database specific expressions and options for sorting -by column +It is also possible to use database specific expressions and options for sorting by column ```ruby order_by(:title) do |order_clause| @@ -226,8 +217,8 @@ end ## Custom row class -In order to add special class to table rows pass the proc object as a -`:row_class` option of the `index` method. +In order to add special class to table rows pass the proc object as a `:row_class` option +of the `index` method. ```ruby index row_class: ->elem { 'active' if elem.active? } do diff --git a/lib/active_admin/views/index_as_table.rb b/lib/active_admin/views/index_as_table.rb index a5955ae5e0c..15b338af080 100644 --- a/lib/active_admin/views/index_as_table.rb +++ b/lib/active_admin/views/index_as_table.rb @@ -159,6 +159,24 @@ module Views # end # ``` # + # ## Custom sorting + # + # It is also possible to use database specific expressions and options for sorting by column + # + # ```ruby + # order_by(:title) do |order_clause| + # if order_clause.order == 'desc' + # [order_clause.to_sql, 'NULLS LAST'].join(' ') + # else + # [order_clause.to_sql, 'NULLS FIRST'].join(' ') + # end + # end + # + # index do + # column :title + # end + # ``` + # # ## Associated Sorting # # You're normally able to sort columns alphabetically, but by default you From c51a3167e1b84e9afb97b5a7f563fa11dd4a3e0d Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Wed, 28 Jun 2017 21:54:14 +0300 Subject: [PATCH 0659/3836] fixed current_scope rendering in ActiveSidebar [closes #5043] --- features/index/filters.feature | 18 ++++++++++++++++++ lib/active_admin/filters/active_sidebar.rb | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/features/index/filters.feature b/features/index/filters.feature index 9377f78d82e..1ada964f86e 100644 --- a/features/index/filters.feature +++ b/features/index/filters.feature @@ -181,6 +181,24 @@ Feature: Index Filtering And I should see "Non-Fiction" within ".index_table" And the "Jane Doe" checkbox should be checked + Scenario: Filtering posts without default scope + + Given a post with the title "Hello World" written by "Jane Doe" exists + Given an index configuration of: + """ + ActiveAdmin.register Post do + scope :all + scope :published do |posts| + posts.where("published_date IS NOT NULL") + end + + filter :title + end + """ + When I fill in "Title" with "Hello" + And I press "Filter" + Then I should see current filter "title_contains" equal to "Hello" with label "Title contains" + Scenario: Filtering posts by category Given a category named "Mystery" exists And a post with the title "Hello World" written by "Jane Doe" in category "Non-Fiction" exists diff --git a/lib/active_admin/filters/active_sidebar.rb b/lib/active_admin/filters/active_sidebar.rb index 461b87a078a..7449e1dc89d 100644 --- a/lib/active_admin/filters/active_sidebar.rb +++ b/lib/active_admin/filters/active_sidebar.rb @@ -12,7 +12,7 @@ def block -> do active_filters = ActiveAdmin::Filters::Active.new(active_admin_config, assigns[:search]) span do - if active_admin_config.scopes.any? + if current_scope h4 I18n.t("active_admin.search_status.current_scope"), style: 'display: inline' b scope_name(current_scope), class: 'current_scope_name', style: "display: inline" end From eb61a6906c2165998762ec0b94eb94ce1ea78d6c Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 29 Jun 2017 13:16:33 +0300 Subject: [PATCH 0660/3836] do not override global Capybara.ignore_hidden_elements Prefer not to change this global option, and use the :visible option to track elements --- features/step_definitions/batch_action_steps.rb | 4 ++-- features/support/env.rb | 3 --- spec/rails_helper.rb | 3 --- spec/unit/form_builder_spec.rb | 6 +++--- spec/unit/view_helpers/form_helper_spec.rb | 6 +++--- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/features/step_definitions/batch_action_steps.rb b/features/step_definitions/batch_action_steps.rb index 95a782caf63..3c003e590bf 100644 --- a/features/step_definitions/batch_action_steps.rb +++ b/features/step_definitions/batch_action_steps.rb @@ -44,9 +44,9 @@ end Given /^I submit the batch action form with "([^"]*)"$/ do |action| - page.find("#batch_action").set action + page.find("#batch_action", visible: false).set action form = page.find "#collection_selection" - params = page.all("#main_content input").each_with_object({}) do |input, obj| + params = page.all("#main_content input", visible: false).each_with_object({}) do |input, obj| key, value = input['name'], input['value'] if key == 'collection_selection[]' (obj[key] ||= []).push value if input.checked? diff --git a/features/support/env.rb b/features/support/env.rb index c217ed6746e..32fc6218671 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -61,9 +61,6 @@ # steps to use the XPath syntax. Capybara.default_selector = :css -# Make input type=hidden visible -Capybara.ignore_hidden_elements = false - # If you set this to false, any error raised from within your app will bubble # up to your step definition and out to cucumber unless you catch it somewhere # on the way. You can make Rails rescue errors and render error pages on a diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index fa11651457a..d61754a8c40 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -57,6 +57,3 @@ # improve the performance of the specs suite by not logging anything # see http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/ Rails.logger.level = Logger::FATAL - -# Make input type=hidden visible -Capybara.ignore_hidden_elements = false diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb index 242bb13db73..917ee92c9dc 100644 --- a/spec/unit/form_builder_spec.rb +++ b/spec/unit/form_builder_spec.rb @@ -637,7 +637,7 @@ def user end it "should wrap the destroy field in an li with class 'has_many_delete'" do - expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1) + expect(body).to have_selector(".has_many_container > fieldset > ol > li.has_many_delete > input", count: 1, visible: false) end end @@ -647,7 +647,7 @@ def user end it "should not have a boolean field for _destroy" do - expect(body).not_to have_selector("input[name='category[posts_attributes][#{child_num}][_destroy]']") + expect(body).not_to have_selector("input[name='category[posts_attributes][#{child_num}][_destroy]']", visible: :all) end it "should not have a check box with 'Remove' as its label" do @@ -950,7 +950,7 @@ def user eval source end end - expect(body).to have_selector("[id=#{selector}]", count: 2) + expect(body).to have_selector("[id=#{selector}]", count: 2, visible: :all) end end diff --git a/spec/unit/view_helpers/form_helper_spec.rb b/spec/unit/view_helpers/form_helper_spec.rb index 5b68894e18c..ea94629b8d6 100644 --- a/spec/unit/view_helpers/form_helper_spec.rb +++ b/spec/unit/view_helpers/form_helper_spec.rb @@ -26,8 +26,8 @@ it "should render hidden field tags for params" do html = Capybara.string view.hidden_field_tags_for(ActionController::Parameters.new(scope: "All", filter: "None")) - expect(html).to have_selector("input#hidden_active_admin_scope[name=scope][type=hidden][value=All]") - expect(html).to have_selector("input#hidden_active_admin_filter[name=filter][type=hidden][value=None]") + expect(html).to have_selector("input#hidden_active_admin_scope[name=scope][type=hidden][value=All]", visible: false) + expect(html).to have_selector("input#hidden_active_admin_filter[name=filter][type=hidden][value=None]", visible: false) end it "should generate not default id for hidden input" do @@ -36,7 +36,7 @@ it "should filter out the field passed via the option :except" do html = Capybara.string view.hidden_field_tags_for(ActionController::Parameters.new(scope: "All", filter: "None"), except: :filter) - expect(html).to have_selector("input#hidden_active_admin_scope[name=scope][type=hidden][value=All]") + expect(html).to have_selector("input#hidden_active_admin_scope[name=scope][type=hidden][value=All]", visible: false) end end end From 8074c739033645ef02f03c64d88bd32b7ec66047 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 29 Jun 2017 13:32:17 +0300 Subject: [PATCH 0661/3836] fixed visibility logic in tabs feature --- features/show/tabs.feature | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/features/show/tabs.feature b/features/show/tabs.feature index 3a8cfe6f6da..d966102a150 100644 --- a/features/show/tabs.feature +++ b/features/show/tabs.feature @@ -5,6 +5,7 @@ Feature: Show - Tabs Background: Given a post with the title "Hello World" written by "Jane Doe" exists + @javascript Scenario: Set a method to be called on the resource as the title Given a show configuration of: """ @@ -23,5 +24,8 @@ Feature: Show - Tabs end """ Then I should see two tabs "Overview" and "Details" - And I should see "tab 1" - And I should see "tab 2" + And I should see the element "#overview span" + And I should not see the element "#details span" + Then I follow "Details" + And I should not see the element "#overview span" + And I should see the element "#details span" \ No newline at end of file From ee4e66d0e6e5224cad1a8c0a1cd6aa4a9764d189 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Thu, 29 Jun 2017 15:29:23 +0300 Subject: [PATCH 0662/3836] make tabs components work with non ascii titlies --- features/show/tabs.feature | 12 +++++---- lib/active_admin/views/components/tabs.rb | 4 +-- spec/unit/views/components/tabs_spec.rb | 30 ++++++++++++++++++++++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/features/show/tabs.feature b/features/show/tabs.feature index d966102a150..c776b985ebb 100644 --- a/features/show/tabs.feature +++ b/features/show/tabs.feature @@ -16,16 +16,18 @@ Feature: Show - Tabs span "tab 1" end - tab :details do + tab 'テスト', id: :test_non_ascii do span "tab 2" end end end end """ - Then I should see two tabs "Overview" and "Details" + + Then show me the page + Then I should see two tabs "Overview" and "テスト" And I should see the element "#overview span" - And I should not see the element "#details span" - Then I follow "Details" + And I should not see the element "#test_non_ascii span" + Then I follow "テスト" + And I should see the element "#test_non_ascii span" And I should not see the element "#overview span" - And I should see the element "#details span" \ No newline at end of file diff --git a/lib/active_admin/views/components/tabs.rb b/lib/active_admin/views/components/tabs.rb index ede61a3bff0..07870c2af35 100644 --- a/lib/active_admin/views/components/tabs.rb +++ b/lib/active_admin/views/components/tabs.rb @@ -15,8 +15,8 @@ def build(&block) end def build_menu_item(title, options, &block) - options = options.reverse_merge({}) - li { link_to title, "##{title.parameterize}", options } + fragment = options.fetch(:id, title.parameterize) + li { link_to title, "##{fragment}" } end def build_content_item(title, options, &block) diff --git a/spec/unit/views/components/tabs_spec.rb b/spec/unit/views/components/tabs_spec.rb index 9adc1bc99fb..892b769e4c7 100644 --- a/spec/unit/views/components/tabs_spec.rb +++ b/spec/unit/views/components/tabs_spec.rb @@ -3,17 +3,45 @@ RSpec.describe ActiveAdmin::Views::Tabs do describe "creating with the dsl" do context "when creating tabs with a symbol" do + before do + expect(I18n).to receive(:t).at_least(:once).with(:tab_key).and_return "テスト" + end + let(:tabs) do render_arbre_component do tabs do tab :overview + tab I18n.t(:tab_key), { id: :something_unique } end end end + let(:subject) { Capybara.string(tabs.to_s) } + it "should create a tab navigation bar based on the symbol" do - expect(tabs.find_by_tag('li').first.content).to include "Overview" + expect(subject).to have_content('Overview') + end + + it "should have tab with id based on symbol" do + expect(subject).to have_selector('div#overview') + end + + it "should have link with fragment based on symbol" do + expect(subject).to have_selector('a[href="#overview"]') end + + it "should handle translation" do + expect(subject).to have_content('テスト') + end + + it "should have tab with id based on options" do + expect(subject).to have_selector('div#something_unique') + end + + it "should have link with fragment based on options" do + expect(subject).to have_selector('a[href="#something_unique"]') + end + end context "when creating a tab with a block" do From 5b249c71a3cdca0cc063c8af0ba958bc55b6a748 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 29 Jun 2017 14:03:34 -0400 Subject: [PATCH 0663/3836] Remove usage of deprecated `unbind` method This is deprecated in jQuery v3 but no need to even call it since the element itself does not have any event handlers attached. --- app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee b/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee index bdb7b7c0233..01d23b5f440 100644 --- a/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee +++ b/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee @@ -32,7 +32,6 @@ class ActiveAdmin.DropdownMenu @ destroy: -> - @$element.unbind() @$element = null @ From 9eacf87b01af6da93c7bc78db302885fd7a92068 Mon Sep 17 00:00:00 2001 From: Igor Fedoronchuk Date: Fri, 23 Jun 2017 20:32:10 +0300 Subject: [PATCH 0664/3836] Support proc as an input_html option value when declaring filters Example ``` filter :title, as: :select, input_html: proc{ {'data-ajax-url': users_api_url} } ``` --- CHANGELOG.md | 2 ++ lib/active_admin/filters/forms.rb | 2 +- spec/unit/filters/filter_form_builder_spec.rb | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae5ac4e20f0..3340f60178e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ ##### Minor +* Support proc as an input_html option value when declaring filters [#5029][] by [@Fivell][] * Base localization support, better associations handling for active filters sidebar [#4951][] by [@Fivell][] * Allow AA scopes to return paginated collections [#4996][] by [@Fivell][] * Added `scopes_show_count` configuration to setup show_count attribute for scopes globally [#4950][] by [@Fivell][] @@ -164,6 +165,7 @@ Please check [0-6-stable](https://github.com/activeadmin/activeadmin/blob/0-6-st [#4951]: https://github.com/activeadmin/activeadmin/pull/4951 [#4989]: https://github.com/activeadmin/activeadmin/pull/4989 [#4996]: https://github.com/activeadmin/activeadmin/pull/4996 +[#5029]: https://github.com/activeadmin/activeadmin/pull/5029 [@ajw725]: https://github.com/ajw725 diff --git a/lib/active_admin/filters/forms.rb b/lib/active_admin/filters/forms.rb index 279bd2f3de6..153d22880a0 100644 --- a/lib/active_admin/filters/forms.rb +++ b/lib/active_admin/filters/forms.rb @@ -57,7 +57,7 @@ def active_admin_filters_form_for(search, filters, options = {}) filters.each do |attribute, opts| next if opts.key?(:if) && !call_method_or_proc_on(self, opts[:if]) next if opts.key?(:unless) && call_method_or_proc_on(self, opts[:unless]) - + opts[:input_html] = instance_exec(&opts[:input_html]) if opts[:input_html].is_a?(Proc) f.filter attribute, opts.except(:if, :unless) end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb index 750e48537f5..c8121ef7bc9 100644 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ b/spec/unit/filters/filter_form_builder_spec.rb @@ -59,6 +59,14 @@ def filter(name, options = {}) expect(body).to have_selector("label", text: "Title from proc") end end + + describe "input html as proc" do + let(:body) { Capybara.string(filter :title, as: :select, input_html: proc{ {'data-ajax-url': '/'} }) } + + it "should render proper label" do + expect(body).to have_selector('select[data-ajax-url="/"]') + end + end end describe "string attribute" do From 3f3beb5435dce300364d9deec9247f1818fc0720 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Mon, 26 Jun 2017 13:07:18 -0400 Subject: [PATCH 0665/3836] Remove bourbon dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We weren’t using bourbon mixins to begin with so no need for the dependency. --- activeadmin.gemspec | 1 - app/assets/stylesheets/active_admin/mixins/_all.scss | 1 - lib/active_admin.rb | 1 - 3 files changed, 3 deletions(-) diff --git a/activeadmin.gemspec b/activeadmin.gemspec index dd7c2e8ced5..5130c545c9c 100644 --- a/activeadmin.gemspec +++ b/activeadmin.gemspec @@ -19,7 +19,6 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 2.2' s.add_dependency 'arbre', '>= 1.1.1' - s.add_dependency 'bourbon' s.add_dependency 'coffee-rails' s.add_dependency 'formtastic', '~> 3.1' s.add_dependency 'formtastic_i18n' diff --git a/app/assets/stylesheets/active_admin/mixins/_all.scss b/app/assets/stylesheets/active_admin/mixins/_all.scss index 84e764a3009..215bfab1060 100644 --- a/app/assets/stylesheets/active_admin/mixins/_all.scss +++ b/app/assets/stylesheets/active_admin/mixins/_all.scss @@ -6,4 +6,3 @@ @import "active_admin/mixins/sections"; @import "active_admin/mixins/utilities"; @import "active_admin/mixins/typography"; -@import "bourbon"; diff --git a/lib/active_admin.rb b/lib/active_admin.rb index ed02d6b824b..2c4e7d6375c 100644 --- a/lib/active_admin.rb +++ b/lib/active_admin.rb @@ -3,7 +3,6 @@ require 'ransack' require 'ransack_ext' -require 'bourbon' require 'kaminari' require 'formtastic' require 'formtastic_i18n' From 34e05d37d77a2c2506173101a589de023e05ec41 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Fri, 30 Jun 2017 16:02:19 -0400 Subject: [PATCH 0666/3836] Only allow seeded admin user if in development --- lib/generators/active_admin/devise/devise_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generators/active_admin/devise/devise_generator.rb b/lib/generators/active_admin/devise/devise_generator.rb index 9da0aa39610..16ba7709688 100644 --- a/lib/generators/active_admin/devise/devise_generator.rb +++ b/lib/generators/active_admin/devise/devise_generator.rb @@ -59,7 +59,7 @@ def add_default_user_to_seed seeds_file = seeds_paths.existent.first return if seeds_file.nil? || !options[:default_user] - create_user_code = "#{class_name}.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password')" + create_user_code = "#{class_name}.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if Rails.env.development?" append_to_file seeds_file, create_user_code end From 120ceb3809a85ae6679faca66cc8d51b60b4c6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 30 Jun 2017 00:20:20 +0200 Subject: [PATCH 0667/3836] Remove js configuration part from codecov Not using it. --- codecov.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/codecov.yml b/codecov.yml index 776f0ea9eb8..4c9c4a672a2 100644 --- a/codecov.yml +++ b/codecov.yml @@ -12,6 +12,3 @@ coverage: changes: false patch: true project: true -parsers: - javascript: - enable_partials: false From a9f1ac3f94d98ad18de4d2afc4c913ee1044a10e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 30 Jun 2017 00:21:43 +0200 Subject: [PATCH 0668/3836] Reformat codecov config for my visual pleasure :) --- codecov.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/codecov.yml b/codecov.yml index 4c9c4a672a2..6042df63fd6 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,13 +1,20 @@ +--- + codecov: notify: require_ci_to_pass: true + comment: off + coverage: precision: 2 + range: - - 70.0 - - 100.0 + - 70.0 + - 100.0 + round: down + status: changes: false patch: true From 17f970ebb32696cf43f8dbc92aa7bba05fb44765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 30 Jun 2017 00:22:15 +0200 Subject: [PATCH 0669/3836] Let it be a little more flexible Two digits precision is too strict I think. Let's use one and round it generously, so that the expected decreased in coverage when code is removed affects the status checks less. --- codecov.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codecov.yml b/codecov.yml index 6042df63fd6..a352d79ddb7 100644 --- a/codecov.yml +++ b/codecov.yml @@ -7,13 +7,13 @@ codecov: comment: off coverage: - precision: 2 + precision: 1 range: - 70.0 - 100.0 - round: down + round: up status: changes: false From 73423bd8cc2b9785f77ebde410357d8ca5d590b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Sun, 2 Jul 2017 09:41:41 +0200 Subject: [PATCH 0670/3836] Fix regression causing unexpected coverage decrease --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index aac2cbd91f8..569d05bdfb3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1 +1 @@ -require 'simplecov' if ENV["COVERAGE"] == true +require 'simplecov' if ENV["COVERAGE"] == "true" From 2f263022d4bea3d24ed7a0588fdecb7c8c1370c6 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 4 Jul 2017 20:07:37 -0400 Subject: [PATCH 0671/3836] Add spacing between links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This isn’t ideal but this is used in various layouts that would need updating. Best way to fix this is to bring back the br tags and tackle more redesign work in v2 and #3862. --- app/views/active_admin/devise/shared/_links.erb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/views/active_admin/devise/shared/_links.erb b/app/views/active_admin/devise/shared/_links.erb index 63813da717f..1fe95f6a190 100644 --- a/app/views/active_admin/devise/shared/_links.erb +++ b/app/views/active_admin/devise/shared/_links.erb @@ -1,27 +1,33 @@ <%- if controller_name != 'sessions' %> <% scope = Devise::Mapping.find_scope!(resource_name) %> <%= link_to t('active_admin.devise.links.sign_in'), send(:"new_#{scope}_session_path") %> +
        <% end -%> <%- if devise_mapping.registerable? && controller_name != 'registrations' %> <%= link_to t('active_admin.devise.links.sign_up'), new_registration_path(resource_name) %> +
        <% end -%> <%- if devise_mapping.recoverable? && controller_name != 'passwords' %> <%= link_to t('active_admin.devise.links.forgot_your_password'), new_password_path(resource_name) %> +
        <% end -%> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> <%= link_to t('active_admin.devise.links.resend_confirmation_instructions'), new_confirmation_path(resource_name) %> +
        <% end -%> <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> <%= link_to t('active_admin.devise.links.resend_unlock_instructions'), new_unlock_path(resource_name) %> +
        <% end -%> <%- if devise_mapping.omniauthable? %> <%- resource_class.omniauth_providers.each do |provider| %> <%= link_to t('active_admin.devise.links.sign_in_with_omniauth_provider', provider: provider.to_s.titleize), omniauth_authorize_path(resource_name, provider) %> +
        <% end -%> <% end -%> From 3fe0a55af4e9743bf1168dd43eef471870051ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 5 Jul 2017 09:36:09 +0200 Subject: [PATCH 0672/3836] Let jquery-ui-rails 6.0 be used in tests --- gemfiles/rails_42.gemfile | 1 - gemfiles/rails_50.gemfile | 1 - gemfiles/rails_51.gemfile | 1 - 3 files changed, 3 deletions(-) diff --git a/gemfiles/rails_42.gemfile b/gemfiles/rails_42.gemfile index 27d8e6d3dec..531a85171f4 100644 --- a/gemfiles/rails_42.gemfile +++ b/gemfiles/rails_42.gemfile @@ -3,7 +3,6 @@ source "https://rubygems.org" eval_gemfile(File.expand_path(File.join("..", "Gemfile"), __dir__)) gem "rails", "4.2.8" -gem "jquery-ui-rails", "~> 5.0" gem "devise", "~> 3.5" gem "draper", "~> 2.1" gem "activerecord-jdbcsqlite3-adapter", platforms: :jruby diff --git a/gemfiles/rails_50.gemfile b/gemfiles/rails_50.gemfile index 1e200a0e507..683c5802c4a 100644 --- a/gemfiles/rails_50.gemfile +++ b/gemfiles/rails_50.gemfile @@ -3,7 +3,6 @@ source "https://rubygems.org" eval_gemfile(File.expand_path(File.join("..", "Gemfile"), __dir__)) gem "rails", "5.0.3" -gem "jquery-ui-rails", "~> 5.0" gem "devise", "~> 4.0" gem "draper", "~> 3.0" gem "activerecord-jdbcsqlite3-adapter", github: "jruby/activerecord-jdbc-adapter", branch: "rails-5", platforms: :jruby diff --git a/gemfiles/rails_51.gemfile b/gemfiles/rails_51.gemfile index 7cd0dd806ab..5cd6561e8aa 100644 --- a/gemfiles/rails_51.gemfile +++ b/gemfiles/rails_51.gemfile @@ -3,7 +3,6 @@ source "https://rubygems.org" eval_gemfile(File.expand_path(File.join("..", "Gemfile"), __dir__)) gem "rails", "5.1.1" -gem "jquery-ui-rails", "~> 5.0" gem "devise", "~> 4.3" gem "draper", "~> 3.0" gem "activerecord-jdbcsqlite3-adapter", github: "jruby/activerecord-jdbc-adapter", branch: "rails-5", platforms: :jruby From 05ae23f0b0fd65b90f8ebe22047765eabe34295d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Prod=27homme?= Date: Wed, 5 Jul 2017 10:30:48 +0200 Subject: [PATCH 0673/3836] complete fr translation --- config/locales/fr.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 55315185ae9..6194bc17ad6 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -8,6 +8,7 @@ fr: edit: "Modifier" delete: "Supprimer" delete_confirmation: "Êtes-vous certain de vouloir supprimer ceci ?" + create_another: "Créer autre %{model}" new_model: "Créer %{model}" edit_model: "Modifier %{model}" delete_model: "Supprimer %{model}" @@ -33,6 +34,8 @@ fr: less_than: "Plus petit que" gteq_datetime: "Ultérieur ou égal à" lteq_datetime: "Antérieur ou égal à" + from: "De" + to: "À" search_status: headline: "Statut de la recherche :" current_scope: "Etendu du filtre :" @@ -124,6 +127,10 @@ fr: sign_in_with_omniauth_provider: "Connectez-vous avec %{provider}" resend_unlock_instructions: "Renvoyer les informations de déverrouillage" resend_confirmation_instructions: "Renvoyer les instructions de confirmation" + unsupported_browser: + headline: "Veuillez noter que ActiveAdmin ne supporte plus les versions d'Internet Explorer 8 ou moins." + recommendation: "Nous vous recommandons de mettre à jour votre navigateur pour améliorer votre expérience." + turn_off_compatibility_view: "Si vous utilisez IE 9 ou une version ultérieure, assurez-vous d'activer \"Affichage de compatibilité\"." access_denied: message: "Vous n'êtes pas autorisé à exécuter cette action" index_list: From 632205c73613d94c8060545fda5d604a1568b4ab Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Thu, 29 Jun 2017 16:57:12 -0400 Subject: [PATCH 0674/3836] Use jquery3 as default --- app/assets/javascripts/active_admin/base.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/active_admin/base.js.coffee b/app/assets/javascripts/active_admin/base.js.coffee index 6f184cafcc5..93aa5ed4f47 100644 --- a/app/assets/javascripts/active_admin/base.js.coffee +++ b/app/assets/javascripts/active_admin/base.js.coffee @@ -1,4 +1,4 @@ -#= require jquery +#= require jquery3 #= require ./jquery_ui #= require jquery_ujs #= require_self From 60bd629df93bc2433d128082c71faecc0433b0d3 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Tue, 4 Jul 2017 19:50:15 -0400 Subject: [PATCH 0675/3836] Include jQuery migrate plugin to fix jQuery UI errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What’s funny is that we actually need to include this because jQuery UI hasn’t been updated to remove use of deprecated or removes features. Its also recommended from jQuery org maintainers to use this for upgrading while using jQuery UI. --- .../javascripts/active_admin/base.js.coffee | 1 + .../javascripts/jquery-migrate-3.0.0.js | 540 ++++++++++++++++++ 2 files changed, 541 insertions(+) create mode 100644 vendor/assets/javascripts/jquery-migrate-3.0.0.js diff --git a/app/assets/javascripts/active_admin/base.js.coffee b/app/assets/javascripts/active_admin/base.js.coffee index 93aa5ed4f47..9ebe164f4f4 100644 --- a/app/assets/javascripts/active_admin/base.js.coffee +++ b/app/assets/javascripts/active_admin/base.js.coffee @@ -1,4 +1,5 @@ #= require jquery3 +#= require jquery-migrate-3.0.0 #= require ./jquery_ui #= require jquery_ujs #= require_self diff --git a/vendor/assets/javascripts/jquery-migrate-3.0.0.js b/vendor/assets/javascripts/jquery-migrate-3.0.0.js new file mode 100644 index 00000000000..05b1a803c2b --- /dev/null +++ b/vendor/assets/javascripts/jquery-migrate-3.0.0.js @@ -0,0 +1,540 @@ +/*! + * jQuery Migrate - v3.0.0 - 2016-06-09 + * Copyright jQuery Foundation and other contributors + */ +(function( jQuery, window ) { +"use strict"; + + +jQuery.migrateVersion = "3.0.0"; + + +( function() { + + // Support: IE9 only + // IE9 only creates console object when dev tools are first opened + // Also, avoid Function#bind here to simplify PhantomJS usage + var log = window.console && window.console.log && + function() { window.console.log.apply( window.console, arguments ); }, + rbadVersions = /^[12]\./; + + if ( !log ) { + return; + } + + // Need jQuery 3.0.0+ and no older Migrate loaded + if ( !jQuery || rbadVersions.test( jQuery.fn.jquery ) ) { + log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" ); + } + if ( jQuery.migrateWarnings ) { + log( "JQMIGRATE: Migrate plugin loaded multiple times" ); + } + + // Show a message on the console so devs know we're active + log( "JQMIGRATE: Migrate is installed" + + ( jQuery.migrateMute ? "" : " with logging active" ) + + ", version " + jQuery.migrateVersion ); + +} )(); + +var warnedAbout = {}; + +// List of warnings already given; public read only +jQuery.migrateWarnings = []; + +// Set to false to disable traces that appear with warnings +if ( jQuery.migrateTrace === undefined ) { + jQuery.migrateTrace = true; +} + +// Forget any warnings we've already given; public +jQuery.migrateReset = function() { + warnedAbout = {}; + jQuery.migrateWarnings.length = 0; +}; + +function migrateWarn( msg ) { + var console = window.console; + if ( !warnedAbout[ msg ] ) { + warnedAbout[ msg ] = true; + jQuery.migrateWarnings.push( msg ); + if ( console && console.warn && !jQuery.migrateMute ) { + console.warn( "JQMIGRATE: " + msg ); + if ( jQuery.migrateTrace && console.trace ) { + console.trace(); + } + } + } +} + +function migrateWarnProp( obj, prop, value, msg ) { + Object.defineProperty( obj, prop, { + configurable: true, + enumerable: true, + get: function() { + migrateWarn( msg ); + return value; + } + } ); +} + +if ( document.compatMode === "BackCompat" ) { + + // JQuery has never supported or tested Quirks Mode + migrateWarn( "jQuery is not compatible with Quirks Mode" ); +} + + +var oldInit = jQuery.fn.init, + oldIsNumeric = jQuery.isNumeric, + oldFind = jQuery.find, + rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, + rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; + +jQuery.fn.init = function( arg1 ) { + var args = Array.prototype.slice.call( arguments ); + + if ( typeof arg1 === "string" && arg1 === "#" ) { + + // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0 + migrateWarn( "jQuery( '#' ) is not a valid selector" ); + args[ 0 ] = []; + } + + return oldInit.apply( this, args ); +}; +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.find = function( selector ) { + var args = Array.prototype.slice.call( arguments ); + + // Support: PhantomJS 1.x + // String#match fails to match when used with a //g RegExp, only on some strings + if ( typeof selector === "string" && rattrHashTest.test( selector ) ) { + + // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0 + // First see if qS thinks it's a valid selector, if so avoid a false positive + try { + document.querySelector( selector ); + } catch ( err1 ) { + + // Didn't *look* valid to qSA, warn and try quoting what we think is the value + selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) { + return "[" + attr + op + "\"" + value + "\"]"; + } ); + + // If the regexp *may* have created an invalid selector, don't update it + // Note that there may be false alarms if selector uses jQuery extensions + try { + document.querySelector( selector ); + migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] ); + args[ 0 ] = selector; + } catch ( err2 ) { + migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] ); + } + } + } + + return oldFind.apply( this, args ); +}; + +// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) +var findProp; +for ( findProp in oldFind ) { + if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { + jQuery.find[ findProp ] = oldFind[ findProp ]; + } +} + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" ); + return this.length; +}; + +jQuery.parseJSON = function() { + migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" ); + return JSON.parse.apply( null, arguments ); +}; + +jQuery.isNumeric = function( val ) { + + // The jQuery 2.2.3 implementation of isNumeric + function isNumeric2( obj ) { + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + } + + var newValue = oldIsNumeric( val ), + oldValue = isNumeric2( val ); + + if ( newValue !== oldValue ) { + migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" ); + } + + return oldValue; +}; + +migrateWarnProp( jQuery, "unique", jQuery.uniqueSort, + "jQuery.unique is deprecated, use jQuery.uniqueSort" ); + +// Now jQuery.expr.pseudos is the standard incantation +migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, + "jQuery.expr.filters is now jQuery.expr.pseudos" ); +migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, + "jQuery.expr[\":\"] is now jQuery.expr.pseudos" ); + + +var oldAjax = jQuery.ajax; + +jQuery.ajax = function( ) { + var jQXHR = oldAjax.apply( this, arguments ); + + // Be sure we got a jQXHR (e.g., not sync) + if ( jQXHR.promise ) { + migrateWarnProp( jQXHR, "success", jQXHR.done, + "jQXHR.success is deprecated and removed" ); + migrateWarnProp( jQXHR, "error", jQXHR.fail, + "jQXHR.error is deprecated and removed" ); + migrateWarnProp( jQXHR, "complete", jQXHR.always, + "jQXHR.complete is deprecated and removed" ); + } + + return jQXHR; +}; + + +var oldRemoveAttr = jQuery.fn.removeAttr, + oldToggleClass = jQuery.fn.toggleClass, + rmatchNonSpace = /\S+/g; + +jQuery.fn.removeAttr = function( name ) { + var self = this; + + jQuery.each( name.match( rmatchNonSpace ), function( i, attr ) { + if ( jQuery.expr.match.bool.test( attr ) ) { + migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr ); + self.prop( attr, false ); + } + } ); + + return oldRemoveAttr.apply( this, arguments ); +}; + +jQuery.fn.toggleClass = function( state ) { + + // Only deprecating no-args or single boolean arg + if ( state !== undefined && typeof state !== "boolean" ) { + return oldToggleClass.apply( this, arguments ); + } + + migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" ); + + // Toggle entire class name of each element + return this.each( function() { + var className = this.getAttribute && this.getAttribute( "class" ) || ""; + + if ( className ) { + jQuery.data( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || state === false ? + "" : + jQuery.data( this, "__className__" ) || "" + ); + } + } ); +}; + + +var internalSwapCall = false; + +// If this version of jQuery has .swap(), don't false-alarm on internal uses +if ( jQuery.swap ) { + jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) { + var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get; + + if ( oldHook ) { + jQuery.cssHooks[ name ].get = function() { + var ret; + + internalSwapCall = true; + ret = oldHook.apply( this, arguments ); + internalSwapCall = false; + return ret; + }; + } + } ); +} + +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + if ( !internalSwapCall ) { + migrateWarn( "jQuery.swap() is undocumented and deprecated" ); + } + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + +var oldData = jQuery.data; + +jQuery.data = function( elem, name, value ) { + var curData; + + // If the name is transformed, look for the un-transformed name in the data object + if ( name && name !== jQuery.camelCase( name ) ) { + curData = jQuery.hasData( elem ) && oldData.call( this, elem ); + if ( curData && name in curData ) { + migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name ); + if ( arguments.length > 2 ) { + curData[ name ] = value; + } + return curData[ name ]; + } + } + + return oldData.apply( this, arguments ); +}; + +var oldTweenRun = jQuery.Tween.prototype.run; + +jQuery.Tween.prototype.run = function( percent ) { + if ( jQuery.easing[ this.easing ].length > 1 ) { + migrateWarn( + "easing function " + + "\"jQuery.easing." + this.easing.toString() + + "\" should use only first argument" + ); + + jQuery.easing[ this.easing ] = jQuery.easing[ this.easing ].bind( + jQuery.easing, + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } + + oldTweenRun.apply( this, arguments ); +}; + +var oldLoad = jQuery.fn.load, + originalFix = jQuery.event.fix; + +jQuery.event.props = []; +jQuery.event.fixHooks = {}; + +jQuery.event.fix = function( originalEvent ) { + var event, + type = originalEvent.type, + fixHook = this.fixHooks[ type ], + props = jQuery.event.props; + + if ( props.length ) { + migrateWarn( "jQuery.event.props are deprecated and removed: " + props.join() ); + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + + if ( fixHook && !fixHook._migrated_ ) { + fixHook._migrated_ = true; + migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type ); + if ( ( props = fixHook.props ) && props.length ) { + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + } + + event = originalFix.call( this, originalEvent ); + + return fixHook && fixHook.filter ? fixHook.filter( event, originalEvent ) : event; +}; + +jQuery.each( [ "load", "unload", "error" ], function( _, name ) { + + jQuery.fn[ name ] = function() { + var args = Array.prototype.slice.call( arguments, 0 ); + + // If this is an ajax load() the first arg should be the string URL; + // technically this could also be the "Anything" arg of the event .load() + // which just goes to show why this dumb signature has been deprecated! + // jQuery custom builds that exclude the Ajax module justifiably die here. + if ( name === "load" && typeof args[ 0 ] === "string" ) { + return oldLoad.apply( this, args ); + } + + migrateWarn( "jQuery.fn." + name + "() is deprecated" ); + + args.splice( 0, 0, name ); + if ( arguments.length ) { + return this.on.apply( this, args ); + } + + // Use .triggerHandler here because: + // - load and unload events don't need to bubble, only applied to window or image + // - error event should not bubble to window, although it does pre-1.7 + // See http://bugs.jquery.com/ticket/11820 + this.triggerHandler.apply( this, args ); + return this; + }; + +} ); + +// Trigger "ready" event only once, on document ready +jQuery( function() { + jQuery( document ).triggerHandler( "ready" ); +} ); + +jQuery.event.special.ready = { + setup: function() { + if ( this === document ) { + migrateWarn( "'ready' event is deprecated" ); + } + } +}; + +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + migrateWarn( "jQuery.fn.bind() is deprecated" ); + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + migrateWarn( "jQuery.fn.unbind() is deprecated" ); + return this.off( types, null, fn ); + }, + delegate: function( selector, types, data, fn ) { + migrateWarn( "jQuery.fn.delegate() is deprecated" ); + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + migrateWarn( "jQuery.fn.undelegate() is deprecated" ); + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + } +} ); + + +var oldOffset = jQuery.fn.offset; + +jQuery.fn.offset = function() { + var docElem, + elem = this[ 0 ], + origin = { top: 0, left: 0 }; + + if ( !elem || !elem.nodeType ) { + migrateWarn( "jQuery.fn.offset() requires a valid DOM element" ); + return origin; + } + + docElem = ( elem.ownerDocument || document ).documentElement; + if ( !jQuery.contains( docElem, elem ) ) { + migrateWarn( "jQuery.fn.offset() requires an element connected to a document" ); + return origin; + } + + return oldOffset.apply( this, arguments ); +}; + + +var oldParam = jQuery.param; + +jQuery.param = function( data, traditional ) { + var ajaxTraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + + if ( traditional === undefined && ajaxTraditional ) { + + migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" ); + traditional = ajaxTraditional; + } + + return oldParam.call( this, data, traditional ); +}; + +var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack; + +jQuery.fn.andSelf = function() { + migrateWarn( "jQuery.fn.andSelf() replaced by jQuery.fn.addBack()" ); + return oldSelf.apply( this, arguments ); +}; + + +var oldDeferred = jQuery.Deferred, + tuples = [ + + // Action, add listener, callbacks, .then handlers, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ) ] + ]; + +jQuery.Deferred = function( func ) { + var deferred = oldDeferred(), + promise = deferred.promise(); + + deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + migrateWarn( "deferred.pipe() is deprecated" ); + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // Deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + + }; + + if ( func ) { + func.call( deferred, deferred ); + } + + return deferred; +}; + + + +})( jQuery, window ); From 2caa8ce2237016735041ce28ff87fbb9e8431777 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Wed, 5 Jul 2017 11:41:40 -0400 Subject: [PATCH 0676/3836] Remove migrate plugin --- .../javascripts/active_admin/base.js.coffee | 1 - .../javascripts/jquery-migrate-3.0.0.js | 540 ------------------ 2 files changed, 541 deletions(-) delete mode 100644 vendor/assets/javascripts/jquery-migrate-3.0.0.js diff --git a/app/assets/javascripts/active_admin/base.js.coffee b/app/assets/javascripts/active_admin/base.js.coffee index 9ebe164f4f4..93aa5ed4f47 100644 --- a/app/assets/javascripts/active_admin/base.js.coffee +++ b/app/assets/javascripts/active_admin/base.js.coffee @@ -1,5 +1,4 @@ #= require jquery3 -#= require jquery-migrate-3.0.0 #= require ./jquery_ui #= require jquery_ujs #= require_self diff --git a/vendor/assets/javascripts/jquery-migrate-3.0.0.js b/vendor/assets/javascripts/jquery-migrate-3.0.0.js deleted file mode 100644 index 05b1a803c2b..00000000000 --- a/vendor/assets/javascripts/jquery-migrate-3.0.0.js +++ /dev/null @@ -1,540 +0,0 @@ -/*! - * jQuery Migrate - v3.0.0 - 2016-06-09 - * Copyright jQuery Foundation and other contributors - */ -(function( jQuery, window ) { -"use strict"; - - -jQuery.migrateVersion = "3.0.0"; - - -( function() { - - // Support: IE9 only - // IE9 only creates console object when dev tools are first opened - // Also, avoid Function#bind here to simplify PhantomJS usage - var log = window.console && window.console.log && - function() { window.console.log.apply( window.console, arguments ); }, - rbadVersions = /^[12]\./; - - if ( !log ) { - return; - } - - // Need jQuery 3.0.0+ and no older Migrate loaded - if ( !jQuery || rbadVersions.test( jQuery.fn.jquery ) ) { - log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" ); - } - if ( jQuery.migrateWarnings ) { - log( "JQMIGRATE: Migrate plugin loaded multiple times" ); - } - - // Show a message on the console so devs know we're active - log( "JQMIGRATE: Migrate is installed" + - ( jQuery.migrateMute ? "" : " with logging active" ) + - ", version " + jQuery.migrateVersion ); - -} )(); - -var warnedAbout = {}; - -// List of warnings already given; public read only -jQuery.migrateWarnings = []; - -// Set to false to disable traces that appear with warnings -if ( jQuery.migrateTrace === undefined ) { - jQuery.migrateTrace = true; -} - -// Forget any warnings we've already given; public -jQuery.migrateReset = function() { - warnedAbout = {}; - jQuery.migrateWarnings.length = 0; -}; - -function migrateWarn( msg ) { - var console = window.console; - if ( !warnedAbout[ msg ] ) { - warnedAbout[ msg ] = true; - jQuery.migrateWarnings.push( msg ); - if ( console && console.warn && !jQuery.migrateMute ) { - console.warn( "JQMIGRATE: " + msg ); - if ( jQuery.migrateTrace && console.trace ) { - console.trace(); - } - } - } -} - -function migrateWarnProp( obj, prop, value, msg ) { - Object.defineProperty( obj, prop, { - configurable: true, - enumerable: true, - get: function() { - migrateWarn( msg ); - return value; - } - } ); -} - -if ( document.compatMode === "BackCompat" ) { - - // JQuery has never supported or tested Quirks Mode - migrateWarn( "jQuery is not compatible with Quirks Mode" ); -} - - -var oldInit = jQuery.fn.init, - oldIsNumeric = jQuery.isNumeric, - oldFind = jQuery.find, - rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, - rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; - -jQuery.fn.init = function( arg1 ) { - var args = Array.prototype.slice.call( arguments ); - - if ( typeof arg1 === "string" && arg1 === "#" ) { - - // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0 - migrateWarn( "jQuery( '#' ) is not a valid selector" ); - args[ 0 ] = []; - } - - return oldInit.apply( this, args ); -}; -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.find = function( selector ) { - var args = Array.prototype.slice.call( arguments ); - - // Support: PhantomJS 1.x - // String#match fails to match when used with a //g RegExp, only on some strings - if ( typeof selector === "string" && rattrHashTest.test( selector ) ) { - - // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0 - // First see if qS thinks it's a valid selector, if so avoid a false positive - try { - document.querySelector( selector ); - } catch ( err1 ) { - - // Didn't *look* valid to qSA, warn and try quoting what we think is the value - selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) { - return "[" + attr + op + "\"" + value + "\"]"; - } ); - - // If the regexp *may* have created an invalid selector, don't update it - // Note that there may be false alarms if selector uses jQuery extensions - try { - document.querySelector( selector ); - migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] ); - args[ 0 ] = selector; - } catch ( err2 ) { - migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] ); - } - } - } - - return oldFind.apply( this, args ); -}; - -// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) -var findProp; -for ( findProp in oldFind ) { - if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { - jQuery.find[ findProp ] = oldFind[ findProp ]; - } -} - -// The number of elements contained in the matched element set -jQuery.fn.size = function() { - migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" ); - return this.length; -}; - -jQuery.parseJSON = function() { - migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" ); - return JSON.parse.apply( null, arguments ); -}; - -jQuery.isNumeric = function( val ) { - - // The jQuery 2.2.3 implementation of isNumeric - function isNumeric2( obj ) { - var realStringObj = obj && obj.toString(); - return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; - } - - var newValue = oldIsNumeric( val ), - oldValue = isNumeric2( val ); - - if ( newValue !== oldValue ) { - migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" ); - } - - return oldValue; -}; - -migrateWarnProp( jQuery, "unique", jQuery.uniqueSort, - "jQuery.unique is deprecated, use jQuery.uniqueSort" ); - -// Now jQuery.expr.pseudos is the standard incantation -migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, - "jQuery.expr.filters is now jQuery.expr.pseudos" ); -migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, - "jQuery.expr[\":\"] is now jQuery.expr.pseudos" ); - - -var oldAjax = jQuery.ajax; - -jQuery.ajax = function( ) { - var jQXHR = oldAjax.apply( this, arguments ); - - // Be sure we got a jQXHR (e.g., not sync) - if ( jQXHR.promise ) { - migrateWarnProp( jQXHR, "success", jQXHR.done, - "jQXHR.success is deprecated and removed" ); - migrateWarnProp( jQXHR, "error", jQXHR.fail, - "jQXHR.error is deprecated and removed" ); - migrateWarnProp( jQXHR, "complete", jQXHR.always, - "jQXHR.complete is deprecated and removed" ); - } - - return jQXHR; -}; - - -var oldRemoveAttr = jQuery.fn.removeAttr, - oldToggleClass = jQuery.fn.toggleClass, - rmatchNonSpace = /\S+/g; - -jQuery.fn.removeAttr = function( name ) { - var self = this; - - jQuery.each( name.match( rmatchNonSpace ), function( i, attr ) { - if ( jQuery.expr.match.bool.test( attr ) ) { - migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr ); - self.prop( attr, false ); - } - } ); - - return oldRemoveAttr.apply( this, arguments ); -}; - -jQuery.fn.toggleClass = function( state ) { - - // Only deprecating no-args or single boolean arg - if ( state !== undefined && typeof state !== "boolean" ) { - return oldToggleClass.apply( this, arguments ); - } - - migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" ); - - // Toggle entire class name of each element - return this.each( function() { - var className = this.getAttribute && this.getAttribute( "class" ) || ""; - - if ( className ) { - jQuery.data( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || state === false ? - "" : - jQuery.data( this, "__className__" ) || "" - ); - } - } ); -}; - - -var internalSwapCall = false; - -// If this version of jQuery has .swap(), don't false-alarm on internal uses -if ( jQuery.swap ) { - jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) { - var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get; - - if ( oldHook ) { - jQuery.cssHooks[ name ].get = function() { - var ret; - - internalSwapCall = true; - ret = oldHook.apply( this, arguments ); - internalSwapCall = false; - return ret; - }; - } - } ); -} - -jQuery.swap = function( elem, options, callback, args ) { - var ret, name, - old = {}; - - if ( !internalSwapCall ) { - migrateWarn( "jQuery.swap() is undocumented and deprecated" ); - } - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.apply( elem, args || [] ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - -var oldData = jQuery.data; - -jQuery.data = function( elem, name, value ) { - var curData; - - // If the name is transformed, look for the un-transformed name in the data object - if ( name && name !== jQuery.camelCase( name ) ) { - curData = jQuery.hasData( elem ) && oldData.call( this, elem ); - if ( curData && name in curData ) { - migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name ); - if ( arguments.length > 2 ) { - curData[ name ] = value; - } - return curData[ name ]; - } - } - - return oldData.apply( this, arguments ); -}; - -var oldTweenRun = jQuery.Tween.prototype.run; - -jQuery.Tween.prototype.run = function( percent ) { - if ( jQuery.easing[ this.easing ].length > 1 ) { - migrateWarn( - "easing function " + - "\"jQuery.easing." + this.easing.toString() + - "\" should use only first argument" - ); - - jQuery.easing[ this.easing ] = jQuery.easing[ this.easing ].bind( - jQuery.easing, - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } - - oldTweenRun.apply( this, arguments ); -}; - -var oldLoad = jQuery.fn.load, - originalFix = jQuery.event.fix; - -jQuery.event.props = []; -jQuery.event.fixHooks = {}; - -jQuery.event.fix = function( originalEvent ) { - var event, - type = originalEvent.type, - fixHook = this.fixHooks[ type ], - props = jQuery.event.props; - - if ( props.length ) { - migrateWarn( "jQuery.event.props are deprecated and removed: " + props.join() ); - while ( props.length ) { - jQuery.event.addProp( props.pop() ); - } - } - - if ( fixHook && !fixHook._migrated_ ) { - fixHook._migrated_ = true; - migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type ); - if ( ( props = fixHook.props ) && props.length ) { - while ( props.length ) { - jQuery.event.addProp( props.pop() ); - } - } - } - - event = originalFix.call( this, originalEvent ); - - return fixHook && fixHook.filter ? fixHook.filter( event, originalEvent ) : event; -}; - -jQuery.each( [ "load", "unload", "error" ], function( _, name ) { - - jQuery.fn[ name ] = function() { - var args = Array.prototype.slice.call( arguments, 0 ); - - // If this is an ajax load() the first arg should be the string URL; - // technically this could also be the "Anything" arg of the event .load() - // which just goes to show why this dumb signature has been deprecated! - // jQuery custom builds that exclude the Ajax module justifiably die here. - if ( name === "load" && typeof args[ 0 ] === "string" ) { - return oldLoad.apply( this, args ); - } - - migrateWarn( "jQuery.fn." + name + "() is deprecated" ); - - args.splice( 0, 0, name ); - if ( arguments.length ) { - return this.on.apply( this, args ); - } - - // Use .triggerHandler here because: - // - load and unload events don't need to bubble, only applied to window or image - // - error event should not bubble to window, although it does pre-1.7 - // See http://bugs.jquery.com/ticket/11820 - this.triggerHandler.apply( this, args ); - return this; - }; - -} ); - -// Trigger "ready" event only once, on document ready -jQuery( function() { - jQuery( document ).triggerHandler( "ready" ); -} ); - -jQuery.event.special.ready = { - setup: function() { - if ( this === document ) { - migrateWarn( "'ready' event is deprecated" ); - } - } -}; - -jQuery.fn.extend( { - - bind: function( types, data, fn ) { - migrateWarn( "jQuery.fn.bind() is deprecated" ); - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - migrateWarn( "jQuery.fn.unbind() is deprecated" ); - return this.off( types, null, fn ); - }, - delegate: function( selector, types, data, fn ) { - migrateWarn( "jQuery.fn.delegate() is deprecated" ); - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - migrateWarn( "jQuery.fn.undelegate() is deprecated" ); - return arguments.length === 1 ? - this.off( selector, "**" ) : - this.off( types, selector || "**", fn ); - } -} ); - - -var oldOffset = jQuery.fn.offset; - -jQuery.fn.offset = function() { - var docElem, - elem = this[ 0 ], - origin = { top: 0, left: 0 }; - - if ( !elem || !elem.nodeType ) { - migrateWarn( "jQuery.fn.offset() requires a valid DOM element" ); - return origin; - } - - docElem = ( elem.ownerDocument || document ).documentElement; - if ( !jQuery.contains( docElem, elem ) ) { - migrateWarn( "jQuery.fn.offset() requires an element connected to a document" ); - return origin; - } - - return oldOffset.apply( this, arguments ); -}; - - -var oldParam = jQuery.param; - -jQuery.param = function( data, traditional ) { - var ajaxTraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; - - if ( traditional === undefined && ajaxTraditional ) { - - migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" ); - traditional = ajaxTraditional; - } - - return oldParam.call( this, data, traditional ); -}; - -var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack; - -jQuery.fn.andSelf = function() { - migrateWarn( "jQuery.fn.andSelf() replaced by jQuery.fn.addBack()" ); - return oldSelf.apply( this, arguments ); -}; - - -var oldDeferred = jQuery.Deferred, - tuples = [ - - // Action, add listener, callbacks, .then handlers, final state - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), "rejected" ], - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ) ] - ]; - -jQuery.Deferred = function( func ) { - var deferred = oldDeferred(), - promise = deferred.promise(); - - deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - - migrateWarn( "deferred.pipe() is deprecated" ); - - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - - // Deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this === promise ? newDefer.promise() : this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - - }; - - if ( func ) { - func.call( deferred, deferred ); - } - - return deferred; -}; - - - -})( jQuery, window ); From 9393610b6bde5794a5115f23bf9b2cf941f1f518 Mon Sep 17 00:00:00 2001 From: Javier Julio Date: Wed, 5 Jul 2017 11:42:49 -0400 Subject: [PATCH 0677/3836] Add jQuery UI files to vendor directory Only include what we are using. Some dependencies like dialog have the most required files but in turn its dependencies have several other one off dependencies. Biggest win will be in removing that. Sorting will probably be the harder one. --- .../javascripts/active_admin/jquery_ui.js.erb | 23 +- vendor/assets/javascripts/jquery-ui/data.js | 41 + .../jquery-ui/disable-selection.js | 48 + .../javascripts/jquery-ui/escape-selector.js | 23 + .../assets/javascripts/jquery-ui/focusable.js | 86 + vendor/assets/javascripts/jquery-ui/ie.js | 17 + .../assets/javascripts/jquery-ui/keycode.js | 47 + vendor/assets/javascripts/jquery-ui/plugin.js | 46 + .../assets/javascripts/jquery-ui/position.js | 500 ++++ .../jquery-ui/safe-active-element.js | 42 + .../assets/javascripts/jquery-ui/safe-blur.js | 23 + .../javascripts/jquery-ui/scroll-parent.js | 47 + .../assets/javascripts/jquery-ui/tabbable.js | 38 + .../assets/javascripts/jquery-ui/unique-id.js | 51 + .../assets/javascripts/jquery-ui/version.js | 17 + vendor/assets/javascripts/jquery-ui/widget.js | 735 ++++++ .../javascripts/jquery-ui/widgets/button.js | 391 +++ .../jquery-ui/widgets/checkboxradio.js | 300 +++ .../jquery-ui/widgets/controlgroup.js | 300 +++ .../jquery-ui/widgets/datepicker.js | 2123 +++++++++++++++++ .../javascripts/jquery-ui/widgets/dialog.js | 954 ++++++++ .../jquery-ui/widgets/draggable.js | 1259 ++++++++++ .../javascripts/jquery-ui/widgets/mouse.js | 230 ++ .../jquery-ui/widgets/resizable.js | 1207 ++++++++++ .../javascripts/jquery-ui/widgets/sortable.js | 1561 ++++++++++++ .../javascripts/jquery-ui/widgets/tabs.js | 931 ++++++++ 26 files changed, 11022 insertions(+), 18 deletions(-) create mode 100644 vendor/assets/javascripts/jquery-ui/data.js create mode 100644 vendor/assets/javascripts/jquery-ui/disable-selection.js create mode 100644 vendor/assets/javascripts/jquery-ui/escape-selector.js create mode 100644 vendor/assets/javascripts/jquery-ui/focusable.js create mode 100644 vendor/assets/javascripts/jquery-ui/ie.js create mode 100644 vendor/assets/javascripts/jquery-ui/keycode.js create mode 100644 vendor/assets/javascripts/jquery-ui/plugin.js create mode 100644 vendor/assets/javascripts/jquery-ui/position.js create mode 100644 vendor/assets/javascripts/jquery-ui/safe-active-element.js create mode 100644 vendor/assets/javascripts/jquery-ui/safe-blur.js create mode 100644 vendor/assets/javascripts/jquery-ui/scroll-parent.js create mode 100644 vendor/assets/javascripts/jquery-ui/tabbable.js create mode 100644 vendor/assets/javascripts/jquery-ui/unique-id.js create mode 100644 vendor/assets/javascripts/jquery-ui/version.js create mode 100644 vendor/assets/javascripts/jquery-ui/widget.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/button.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/checkboxradio.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/controlgroup.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/datepicker.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/dialog.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/draggable.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/mouse.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/resizable.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/sortable.js create mode 100644 vendor/assets/javascripts/jquery-ui/widgets/tabs.js diff --git a/app/assets/javascripts/active_admin/jquery_ui.js.erb b/app/assets/javascripts/active_admin/jquery_ui.js.erb index 624631bf805..9d75056d560 100644 --- a/app/assets/javascripts/active_admin/jquery_ui.js.erb +++ b/app/assets/javascripts/active_admin/jquery_ui.js.erb @@ -1,18 +1,5 @@ -<% jquery_ui_path = if Jquery::Ui::Rails::VERSION >= "5" - "jquery-ui/" - else - "jquery.ui." - end -%> -<% jquery_ui_widgets_path = - if Jquery::Ui::Rails::VERSION >= "6" - jquery_ui_path + "widgets/" - else - jquery_ui_path - end -%> -<% require_asset "#{jquery_ui_widgets_path}datepicker" %> -<% require_asset "#{jquery_ui_widgets_path}dialog" %> -<% require_asset "#{jquery_ui_widgets_path}sortable" %> -<% require_asset "#{jquery_ui_widgets_path}tabs" %> -<% require_asset "#{jquery_ui_path}widget" %> +<% require_asset "jquery-ui/widgets/datepicker" %> +<% require_asset "jquery-ui/widgets/dialog" %> +<% require_asset "jquery-ui/widgets/sortable" %> +<% require_asset "jquery-ui/widgets/tabs" %> +<% require_asset "jquery-ui/widget" %> diff --git a/vendor/assets/javascripts/jquery-ui/data.js b/vendor/assets/javascripts/jquery-ui/data.js new file mode 100644 index 00000000000..4bb2f97f9ab --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/data.js @@ -0,0 +1,41 @@ +//= require jquery-ui/version + +/*! + * jQuery UI :data 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :data Selector +//>>group: Core +//>>description: Selects elements which have data stored under the specified key. +//>>docs: http://api.jqueryui.com/data-selector/ + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { +return $.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo( function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + } ) : + + // Support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + } +} ); +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/disable-selection.js b/vendor/assets/javascripts/jquery-ui/disable-selection.js new file mode 100644 index 00000000000..ca89e9aab85 --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/disable-selection.js @@ -0,0 +1,48 @@ +//= require jquery-ui/version + +/*! + * jQuery UI Disable Selection 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: disableSelection +//>>group: Core +//>>description: Disable selection of text content within the set of matched elements. +//>>docs: http://api.jqueryui.com/disableSelection/ + +// This file is deprecated +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { + +return $.fn.extend( { + disableSelection: ( function() { + var eventType = "onselectstart" in document.createElement( "div" ) ? + "selectstart" : + "mousedown"; + + return function() { + return this.on( eventType + ".ui-disableSelection", function( event ) { + event.preventDefault(); + } ); + }; + } )(), + + enableSelection: function() { + return this.off( ".ui-disableSelection" ); + } +} ); + +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/escape-selector.js b/vendor/assets/javascripts/jquery-ui/escape-selector.js new file mode 100644 index 00000000000..48d7e629417 --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/escape-selector.js @@ -0,0 +1,23 @@ +//= require jquery-ui/version + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { + +// Internal use only +return $.ui.escapeSelector = ( function() { + var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g; + return function( selector ) { + return selector.replace( selectorEscape, "\\$1" ); + }; +} )(); + +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/focusable.js b/vendor/assets/javascripts/jquery-ui/focusable.js new file mode 100644 index 00000000000..2300ba9efeb --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/focusable.js @@ -0,0 +1,86 @@ +//= require jquery-ui/version + +/*! + * jQuery UI Focusable 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :focusable Selector +//>>group: Core +//>>description: Selects elements which can be focused. +//>>docs: http://api.jqueryui.com/focusable-selector/ + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { + +// Selectors +$.ui.focusable = function( element, hasTabindex ) { + var map, mapName, img, focusableIfVisible, fieldset, + nodeName = element.nodeName.toLowerCase(); + + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap='#" + mapName + "']" ); + return img.length > 0 && img.is( ":visible" ); + } + + if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { + focusableIfVisible = !element.disabled; + + if ( focusableIfVisible ) { + + // Form controls within a disabled fieldset are disabled. + // However, controls within the fieldset's legend do not get disabled. + // Since controls generally aren't placed inside legends, we skip + // this portion of the check. + fieldset = $( element ).closest( "fieldset" )[ 0 ]; + if ( fieldset ) { + focusableIfVisible = !fieldset.disabled; + } + } + } else if ( "a" === nodeName ) { + focusableIfVisible = element.href || hasTabindex; + } else { + focusableIfVisible = hasTabindex; + } + + return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); +}; + +// Support: IE 8 only +// IE 8 doesn't resolve inherit to visible/hidden for computed values +function visible( element ) { + var visibility = element.css( "visibility" ); + while ( visibility === "inherit" ) { + element = element.parent(); + visibility = element.css( "visibility" ); + } + return visibility !== "hidden"; +} + +$.extend( $.expr[ ":" ], { + focusable: function( element ) { + return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); + } +} ); + +return $.ui.focusable; + +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/ie.js b/vendor/assets/javascripts/jquery-ui/ie.js new file mode 100644 index 00000000000..c339bab19c2 --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/ie.js @@ -0,0 +1,17 @@ +//= require jquery-ui/version + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { + +// This file is deprecated +return $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/keycode.js b/vendor/assets/javascripts/jquery-ui/keycode.js new file mode 100644 index 00000000000..7480dfc80c7 --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/keycode.js @@ -0,0 +1,47 @@ +//= require jquery-ui/version + +/*! + * jQuery UI Keycode 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Keycode +//>>group: Core +//>>description: Provide keycodes as keynames +//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { +return $.ui.keyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 +}; + +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/plugin.js b/vendor/assets/javascripts/jquery-ui/plugin.js new file mode 100644 index 00000000000..ce60e7b5eaf --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/plugin.js @@ -0,0 +1,46 @@ +//= require jquery-ui/version + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { + +// $.ui.plugin is deprecated. Use $.widget() extensions instead. +return $.ui.plugin = { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args, allowDisconnected ) { + var i, + set = instance.plugins[ name ]; + + if ( !set ) { + return; + } + + if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || + instance.element[ 0 ].parentNode.nodeType === 11 ) ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } +}; + +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/position.js b/vendor/assets/javascripts/jquery-ui/position.js new file mode 100644 index 00000000000..7f6bc91d789 --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/position.js @@ -0,0 +1,500 @@ +//= require jquery-ui/version + +/*! + * jQuery UI Position 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/position/ + */ + +//>>label: Position +//>>group: Core +//>>description: Positions elements relative to other elements. +//>>docs: http://api.jqueryui.com/position/ +//>>demos: http://jqueryui.com/position/ + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +}( function( $ ) { +( function() { +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} + +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +function getDimensions( elem ) { + var raw = elem[ 0 ]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( $.isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "
        " + + "
        " ), + innerDiv = div.children()[ 0 ]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[ 0 ].clientWidth; + } + + div.remove(); + + return ( cachedScrollbarWidth = w1 - w2 ); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-x" ), + overflowY = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[ 0 ] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, + hasOffset = !isWindow && !isDocument; + return { + element: withinElement, + isWindow: isWindow, + isDocument: isDocument, + offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: withinElement.outerWidth(), + height: withinElement.outerHeight() + }; + } +}; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // Make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + target = $( options.of ), + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[ 0 ].preventDefault ) { + + // Force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + + // Clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // Force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1 ) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // Calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // Reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + } ); + + // Normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each( function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem: elem + } ); + } + } ); + + if ( options.using ) { + + // Adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + } ); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // Element is wider than within + if ( data.collisionWidth > outerWidth ) { + + // Element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - + withinOffset; + position.left += overLeft - newOverRight; + + // Element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + + // Element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + + // Too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + + // Too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + + // Adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // Element is taller than within + if ( data.collisionHeight > outerHeight ) { + + // Element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - + withinOffset; + position.top += overTop - newOverBottom; + + // Element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + + // Element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + + // Too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + + // Too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + + // Adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - + outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - + outerHeight - withinOffset; + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { + position.top += myOffset + atOffset + offset; + } + } else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + + offset - offsetTop; + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +} )(); + +return $.ui.position; + +} ) ); diff --git a/vendor/assets/javascripts/jquery-ui/safe-active-element.js b/vendor/assets/javascripts/jquery-ui/safe-active-element.js new file mode 100644 index 00000000000..69061ea709c --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui/safe-active-element.js @@ -0,0 +1,42 @@ +//= require jquery-ui/version + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} ( function( $ ) { +return $.ui.safeActiveElement = function( document ) { + var activeElement; + + // Support: IE 9 only + // IE9 throws an "Unspecified error" accessing document.activeElement from an