diff --git a/Gemfile b/Gemfile index 55d01f1c..cf4744ee 100644 --- a/Gemfile +++ b/Gemfile @@ -14,13 +14,12 @@ group :development do gem "pry-byebug" gem "rails-dom-testing", "~> 2.2" gem "rspec" + gem "rubocop", "~> 1.68" gem "sequel" gem "sqlite3", "~> 1.7.0" - gem "rubocop", "~> 1.68" group :mongo do gem "bson" gem "mongoid", "~> 9.0" end end - diff --git a/lib/datagrid/core.rb b/lib/datagrid/core.rb index e11830ab..8bc04d8f 100644 --- a/lib/datagrid/core.rb +++ b/lib/datagrid/core.rb @@ -161,9 +161,6 @@ def attributes # grid.attributes = {first_name: 'John', last_name: 'Smith'} # grid.first_name # => 'John' # grid.last_name # => 'Smith' - def attributes=(value) - super - end # @return [Object] Any datagrid attribute value def [](attribute) diff --git a/lib/datagrid/filters/boolean_filter.rb b/lib/datagrid/filters/boolean_filter.rb index f6ff874b..753f3da9 100644 --- a/lib/datagrid/filters/boolean_filter.rb +++ b/lib/datagrid/filters/boolean_filter.rb @@ -5,10 +5,9 @@ module Datagrid module Filters class BooleanFilter < Datagrid::Filters::BaseFilter - # @!visibility private def initialize(grid, name, **opts) - super(grid, name, **opts) + super options[:default] ||= false end diff --git a/lib/datagrid/filters/date_filter.rb b/lib/datagrid/filters/date_filter.rb index f3eccd89..9793698d 100644 --- a/lib/datagrid/filters/date_filter.rb +++ b/lib/datagrid/filters/date_filter.rb @@ -12,9 +12,7 @@ def default_input_options end def apply(grid_object, scope, value) - if value.is_a?(Range) - value = value.begin&.beginning_of_day..value.end&.end_of_day - end + value = value.begin&.beginning_of_day..value.end&.end_of_day if value.is_a?(Range) super end @@ -31,9 +29,7 @@ def format(value) end def default_filter_where(scope, value) - if driver.is_timestamp?(scope, name) - value = Datagrid::Utils.format_date_as_timestamp(value) - end + value = Datagrid::Utils.format_date_as_timestamp(value) if driver.is_timestamp?(scope, name) super end diff --git a/lib/datagrid/filters/dynamic_filter.rb b/lib/datagrid/filters/dynamic_filter.rb index b05721a3..9926ff06 100644 --- a/lib/datagrid/filters/dynamic_filter.rb +++ b/lib/datagrid/filters/dynamic_filter.rb @@ -22,12 +22,12 @@ class DynamicFilter < Datagrid::Filters::BaseFilter def initialize(grid, name, **options, &block) options[:select] ||= default_select options[:operations] ||= DEFAULT_OPERATIONS - options[:include_blank] = false unless options.key?(:include_blank) - super(grid, name, **options, &block) + options[:include_blank] = false unless options.key?(:include_blank) + super end def default_input_options - {**super, type: nil} + { **super, type: nil } end def parse_values(filter) diff --git a/lib/datagrid/filters/enum_filter.rb b/lib/datagrid/filters/enum_filter.rb index ac21aac3..ec154a8e 100644 --- a/lib/datagrid/filters/enum_filter.rb +++ b/lib/datagrid/filters/enum_filter.rb @@ -10,7 +10,7 @@ class EnumFilter < Datagrid::Filters::BaseFilter # @!visibility private def initialize(grid, name, **options, &block) options[:multiple] = true if options[:checkboxes] - super(grid, name, **options, &block) + super raise Datagrid::ConfigurationError, ":select option not specified" unless options[:select] end diff --git a/lib/datagrid/filters/integer_filter.rb b/lib/datagrid/filters/integer_filter.rb index 4ebde9bf..26146ffc 100644 --- a/lib/datagrid/filters/integer_filter.rb +++ b/lib/datagrid/filters/integer_filter.rb @@ -19,9 +19,7 @@ def parse(value) end return value if value.is_a?(Range) - if value.to_i == 0 && value.is_a?(String) && value !~ %r{\A\s*-?0} - return nil - end + return nil if value.to_i.zero? && value.is_a?(String) && value !~ %r{\A\s*-?0} value.to_i end diff --git a/lib/datagrid/filters/ranged_filter.rb b/lib/datagrid/filters/ranged_filter.rb index a18cb184..421a13af 100644 --- a/lib/datagrid/filters/ranged_filter.rb +++ b/lib/datagrid/filters/ranged_filter.rb @@ -3,7 +3,7 @@ module Datagrid module Filters module RangedFilter - SERIALIZED_RANGE = %r{\A(.*)\.{2,3}(.*)\z}.freeze + SERIALIZED_RANGE = %r{\A(.*)\.{2,3}(.*)\z} def parse_values(value) return super unless range? diff --git a/lib/datagrid/form_builder.rb b/lib/datagrid/form_builder.rb index aec1cc08..b9018225 100644 --- a/lib/datagrid/form_builder.rb +++ b/lib/datagrid/form_builder.rb @@ -7,9 +7,9 @@ module FormBuilder # @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name # @param options [Hash] options of rails form input helper # @return [String] a form input html for the corresponding filter - def datagrid_filter(filter_or_attribute, **options, &block) + def datagrid_filter(filter_or_attribute, ...) filter = datagrid_get_filter(filter_or_attribute) - send(filter.form_builder_helper_name, filter, **options, &block) + send(filter.form_builder_helper_name, filter, ...) end # @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name @@ -44,9 +44,7 @@ def datagrid_filter_input(attribute_or_filter, **options, &block) text_area filter.name, value: object.filter_value_as_string(filter), **options, &block when :checkbox value = options.fetch(:value, 1).to_s - if filter.enum_checkboxes? && enum_checkbox_checked?(filter, value) - options = {checked: true, **options} - end + options = { checked: true, **options } if filter.enum_checkboxes? && enum_checkbox_checked?(filter, value) check_box filter.name, options, value when :hidden hidden_field filter.name, **options diff --git a/lib/datagrid/generators/scaffold.rb b/lib/datagrid/generators/scaffold.rb index 0956e461..172c8b5c 100644 --- a/lib/datagrid/generators/scaffold.rb +++ b/lib/datagrid/generators/scaffold.rb @@ -6,168 +6,168 @@ module Datagrid # @!visibility private module Generators - # @!visibility private - class Scaffold < Rails::Generators::NamedBase - include Rails::Generators::ResourceHelpers - - check_class_collision suffix: "Grid" - source_root File.expand_path("#{__FILE__}/../../../templates") - - def create_scaffold - template "base.rb.erb", base_grid_file unless file_exists?(base_grid_file) - template "grid.rb.erb", "app/grids/#{grid_class_name.underscore}.rb" - if file_exists?(grid_controller_file) - inject_into_file grid_controller_file, index_action, after: %r{class .*#{grid_controller_class_name}.*\n} - else - create_file grid_controller_file, controller_code - end - create_file view_file, view_code - route(generate_routing_namespace("resources :#{grid_controller_short_name}")) - gem "kaminari" unless defined?(::Kaminari) || defined?(::WillPaginate) || defined?(::Pagy) - in_root do - { - "css" => " *= require datagrid", - "css.sass" => " *= require datagrid", - "css.scss" => " *= require datagrid", - }.each do |extension, string| - file = "app/assets/stylesheets/application.#{extension}" - if file_exists?(file) - inject_into_file file, "#{string}\n", { before: %r{.*require_self} } # before all + # @!visibility private + class Scaffold < Rails::Generators::NamedBase + include Rails::Generators::ResourceHelpers + + check_class_collision suffix: "Grid" + source_root File.expand_path("#{__FILE__}/../../../templates") + + def create_scaffold + template "base.rb.erb", base_grid_file unless file_exists?(base_grid_file) + template "grid.rb.erb", "app/grids/#{grid_class_name.underscore}.rb" + if file_exists?(grid_controller_file) + inject_into_file grid_controller_file, index_action, after: %r{class .*#{grid_controller_class_name}.*\n} + else + create_file grid_controller_file, controller_code + end + create_file view_file, view_code + route(generate_routing_namespace("resources :#{grid_controller_short_name}")) + gem "kaminari" unless defined?(::Kaminari) || defined?(::WillPaginate) || defined?(::Pagy) + in_root do + { + "css" => " *= require datagrid", + "css.sass" => " *= require datagrid", + "css.scss" => " *= require datagrid", + }.each do |extension, string| + file = "app/assets/stylesheets/application.#{extension}" + if file_exists?(file) + inject_into_file file, "#{string}\n", { before: %r{.*require_self} } # before all + end end end end - end - def view_file - Rails.root.join("app/views").join(controller_file_path).join("index.html.erb") - end + def view_file + Rails.root.join("app/views").join(controller_file_path).join("index.html.erb") + end - def grid_class_name - "#{file_name.camelize.pluralize}Grid" - end + def grid_class_name + "#{file_name.camelize.pluralize}Grid" + end - def grid_base_class - file_exists?("app/grids/base_grid.rb") ? "BaseGrid" : "ApplicationGrid" - end + def grid_base_class + file_exists?("app/grids/base_grid.rb") ? "BaseGrid" : "ApplicationGrid" + end - def grid_controller_class_name - "#{controller_class_name.camelize}Controller" - end + def grid_controller_class_name + "#{controller_class_name.camelize}Controller" + end - def grid_controller_file - Rails.root.join("app/controllers").join("#{grid_controller_class_name.underscore}.rb") - end + def grid_controller_file + Rails.root.join("app/controllers").join("#{grid_controller_class_name.underscore}.rb") + end - def grid_controller_short_name - controller_file_name - end + def grid_controller_short_name + controller_file_name + end - def grid_model_name - file_name.camelize.singularize - end + def grid_model_name + file_name.camelize.singularize + end - def grid_param_name - grid_class_name.underscore - end + def grid_param_name + grid_class_name.underscore + end - def pagination_helper_code - if defined?(::WillPaginate) - "will_paginate(@grid.assets)" - elsif defined?(::Pagy) - "pagy_nav(@pagy)" - else - # Kaminari is default - "paginate(@grid.assets)" + def pagination_helper_code + if defined?(::WillPaginate) + "will_paginate(@grid.assets)" + elsif defined?(::Pagy) + "pagy_nav(@pagy)" + else + # Kaminari is default + "paginate(@grid.assets)" + end end - end - def table_helper_code - if defined?(::Pagy) - "datagrid_table @grid, @records" - else - "datagrid_table @grid" + def table_helper_code + if defined?(::Pagy) + "datagrid_table @grid, @records" + else + "datagrid_table @grid" + end end - end - def base_grid_file - "app/grids/application_grid.rb" - end + def base_grid_file + "app/grids/application_grid.rb" + end - def grid_route_name - "#{controller_class_name.underscore.gsub('/', '_')}_path" - end + def grid_route_name + "#{controller_class_name.underscore.gsub('/', '_')}_path" + end - def index_code - if defined?(::Pagy) - <<-RUBY + def index_code + if defined?(::Pagy) + <<-RUBY @grid = #{grid_class_name}.new(grid_params) @pagy, @assets = pagy(@grid.assets) - RUBY - else - <<-RUBY + RUBY + else + <<-RUBY @grid = #{grid_class_name}.new(grid_params) do |scope| scope.page(params[:page]) end - RUBY + RUBY + end end - end - def controller_code - <<~RUBY - class #{grid_controller_class_name} < ApplicationController - def index - #{index_code.rstrip} - end + def controller_code + <<~RUBY + class #{grid_controller_class_name} < ApplicationController + def index + #{index_code.rstrip} + end - protected + protected - def grid_params - params.fetch(:#{grid_param_name}, {}).permit! + def grid_params + params.fetch(:#{grid_param_name}, {}).permit! + end end - end - RUBY - end + RUBY + end - def view_code - indent(<<~ERB) - <%= datagrid_form_with model: @grid, url: #{grid_route_name} %> + def view_code + indent(<<~ERB) + <%= datagrid_form_with model: @grid, url: #{grid_route_name} %> - <%= #{pagination_helper_code} %> - <%= #{table_helper_code} %> - <%= #{pagination_helper_code} %> - ERB - end + <%= #{pagination_helper_code} %> + <%= #{table_helper_code} %> + <%= #{pagination_helper_code} %> + ERB + end - protected - - def generate_routing_namespace(code) - depth = regular_class_path.length - # Create 'namespace' ladder - # namespace :foo do - # namespace :bar do - namespace_ladder = regular_class_path.each_with_index.map do |ns, i| - indent("namespace :#{ns} do\n", i * 2) - end.join - - # Create route - # get 'baz/index' - route = indent(code, depth * 2) - - # Create `end` ladder - # end - # end - end_ladder = (1..depth).reverse_each.map do |i| - indent("end\n", i * 2) - end.join - - # Combine the 3 parts to generate complete route entry - "#{namespace_ladder}#{route}\n#{end_ladder}" - end + protected + + def generate_routing_namespace(code) + depth = regular_class_path.length + # Create 'namespace' ladder + # namespace :foo do + # namespace :bar do + namespace_ladder = regular_class_path.each_with_index.map do |ns, i| + indent("namespace :#{ns} do\n", i * 2) + end.join + + # Create route + # get 'baz/index' + route = indent(code, depth * 2) + + # Create `end` ladder + # end + # end + end_ladder = (1..depth).reverse_each.map do |i| + indent("end\n", i * 2) + end.join + + # Combine the 3 parts to generate complete route entry + "#{namespace_ladder}#{route}\n#{end_ladder}" + end - def file_exists?(name) - name = Rails.root.join(name) unless name.to_s.first == "/" - File.exist?(name) + def file_exists?(name) + name = Rails.root.join(name) unless name.to_s.first == "/" + File.exist?(name) + end end end - end end diff --git a/lib/datagrid/generators/views.rb b/lib/datagrid/generators/views.rb index 0a852528..3f00a351 100644 --- a/lib/datagrid/generators/views.rb +++ b/lib/datagrid/generators/views.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Datagrid module Generators class Views < Rails::Generators::Base @@ -6,7 +8,7 @@ class Views < Rails::Generators::Base desc "Copies Datagrid partials to your application." def copy_views Dir.glob(File.join(self.class.source_root, "**", "*")).each do |file_path| - relative_path = file_path.sub(self.class.source_root + "/", "") + relative_path = file_path.sub("#{self.class.source_root}/", "") next if relative_path == "_order_for.html.erb" diff --git a/lib/datagrid/helper.rb b/lib/datagrid/helper.rb index dc5e1572..f18b124f 100644 --- a/lib/datagrid/helper.rb +++ b/lib/datagrid/helper.rb @@ -114,9 +114,8 @@ def datagrid_order_for(grid, column, options = {}) # @param grid [Datagrid] grid object # @return [String] form HTML tag markup def datagrid_form_with(**options) - if block_given? - raise ArgumentError, 'datagrid_form_with block argument is invalid. Use form_with instead.' - end + raise ArgumentError, "datagrid_form_with block argument is invalid. Use form_with instead." if block_given? + datagrid_renderer.form_with(**options) end @@ -155,8 +154,8 @@ def datagrid_form_for(grid, options = {}) # Last Name: <%= row.last_name %> # @example # <%= datagrid_row(grid, user, columns: [:first_name, :last_name, :actions]) %> - def datagrid_row(grid, asset, **options, &block) - datagrid_renderer.row(grid, asset, **options, &block) + def datagrid_row(grid, asset, ...) + datagrid_renderer.row(grid, asset, ...) end # Generates an ascending or descending order url for the given column @@ -176,8 +175,8 @@ def datagrid_renderer def datagrid_column_classes(grid, column) Datagrid::Utils.warn_once(<<~MSG) - datagrid_column_classes is deprecated. Assign necessary classes manually. - Correspond to default datagrid/rows partial for example.) + datagrid_column_classes is deprecated. Assign necessary classes manually. + Correspond to default datagrid/rows partial for example.) MSG column = grid.column_by_name(column) order_class = if grid.ordered_by?(column) diff --git a/lib/datagrid/renderer.rb b/lib/datagrid/renderer.rb index 8423cec3..e2fbbc6e 100644 --- a/lib/datagrid/renderer.rb +++ b/lib/datagrid/renderer.rb @@ -27,16 +27,15 @@ def form_for(grid, options = {}) method: :get, as: grid.param_name, local: true, - **options + **options, }, ) end def form_with(**options) grid = options[:model] - if grid&.filters&.empty? - raise ArgumentError, "Grid has no available filters" - end + raise ArgumentError, "Grid has no available filters" if grid&.filters&.empty? + _render_partial("form", options[:partials], { grid: options[:model], options: options }) end diff --git a/lib/datagrid/utils.rb b/lib/datagrid/utils.rb index 3d249952..f97707d8 100644 --- a/lib/datagrid/utils.rb +++ b/lib/datagrid/utils.rb @@ -24,12 +24,14 @@ def translate_from_namespace(namespace, grid_class, key) end def deprecator - defined?(Rails) && Rails.version >= "7.1.0" ? - Rails.deprecator : ActiveSupport::Deprecation + if defined?(Rails) && Rails.version >= "7.1.0" + Rails.deprecator + else + ActiveSupport::Deprecation + end end def warn_once(message, delay = 5) - @warnings ||= {} timestamp = @warnings[message] return false if timestamp && timestamp >= Time.now - delay @@ -99,9 +101,7 @@ def parse_date(value) def parse_datetime(value) return nil if value.blank? return value if value.is_a?(Range) - if defined?(ActiveSupport::TimeWithZone) && value.is_a?(ActiveSupport::TimeWithZone) - return value - end + return value if defined?(ActiveSupport::TimeWithZone) && value.is_a?(ActiveSupport::TimeWithZone) if value.is_a?(String) Array(Datagrid.configuration.datetime_formats).each do |format| @@ -120,7 +120,7 @@ def parse_datetime(value) def format_date_as_timestamp(value) if !value value - # elsif value.is_a?(Array) + # elsif value.is_a?(Array) # value.first&.beginning_of_day..value.last&.end_of_day elsif value.is_a?(Range) value.begin&.beginning_of_day..value.end&.end_of_day diff --git a/spec/datagrid/drivers/active_record_spec.rb b/spec/datagrid/drivers/active_record_spec.rb index d99b77a8..872cb49b 100644 --- a/spec/datagrid/drivers/active_record_spec.rb +++ b/spec/datagrid/drivers/active_record_spec.rb @@ -43,7 +43,7 @@ scope { Entry } filter(:created_at, :date, range: true) do |value, scope, _grid| - scope.joins(:group).where(groups: {created_at: value}) + scope.joins(:group).where(groups: { created_at: value }) end end.assets end diff --git a/spec/datagrid/filters/base_filter_spec.rb b/spec/datagrid/filters/base_filter_spec.rb index 9a6340f8..9f86ec2c 100644 --- a/spec/datagrid/filters/base_filter_spec.rb +++ b/spec/datagrid/filters/base_filter_spec.rb @@ -17,12 +17,11 @@ def name_default end describe "#default_scope?" do - it "identifies filters without custom block" do grid = test_report do scope { Entry } filter(:id, :integer) - filter(:group_id, :integer) do |value, scope| + filter(:group_id, :integer) do |value, _scope| scope("group_id >= ?", value) end end diff --git a/spec/datagrid/filters/boolean_filter_spec.rb b/spec/datagrid/filters/boolean_filter_spec.rb index 96ed6cdf..4b10491c 100644 --- a/spec/datagrid/filters/boolean_filter_spec.rb +++ b/spec/datagrid/filters/boolean_filter_spec.rb @@ -1,4 +1,6 @@ -require 'spec_helper' +# frozen_string_literal: true + +require "spec_helper" describe Datagrid::Filters::BooleanFilter do it "applies default filtering" do diff --git a/spec/datagrid/filters/date_filter_spec.rb b/spec/datagrid/filters/date_filter_spec.rb index 288b1cdc..d42646be 100644 --- a/spec/datagrid/filters/date_filter_spec.rb +++ b/spec/datagrid/filters/date_filter_spec.rb @@ -23,12 +23,12 @@ end it "raises when range assigned to non-range filter" do - expect { + expect do test_report(created_at: 5.day.ago..3.days.ago) do scope { Entry } filter(:created_at, :date) end - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "endless date range argument" do diff --git a/spec/datagrid/form_builder_spec.rb b/spec/datagrid/form_builder_spec.rb index 62794576..98f16fa1 100644 --- a/spec/datagrid/form_builder_spec.rb +++ b/spec/datagrid/form_builder_spec.rb @@ -132,8 +132,8 @@ class MyTemplate context "datetime filter type is text" do let(:_filter) { :created_at } let(:_grid) do - created_at = ActiveSupport::TimeZone['UTC'].local( - 2024, 1, 1, 9, 25, 15 + created_at = ActiveSupport::TimeZone["UTC"].local( + 2024, 1, 1, 9, 25, 15, ) test_report(created_at: created_at) do scope { Entry } diff --git a/spec/datagrid/helper_spec.rb b/spec/datagrid/helper_spec.rb index 4a8ec284..822c60e2 100644 --- a/spec/datagrid/helper_spec.rb +++ b/spec/datagrid/helper_spec.rb @@ -431,10 +431,10 @@ class OrderedGrid < Datagrid::Base object = OrderedGrid.new(descending: true, order: :category) silence_deprecator do expect(subject.datagrid_order_for(object, object.column_by_name(:category))).to equal_to_dom(<<~HTML) -
+ HTML end end @@ -461,16 +461,16 @@ class FormForGrid < Datagrid::Base end object = FormForGrid.new(category: "hello") expect(subject.datagrid_form_for(object, url: "/grid")).to equal_to_dom(<<~HTML) - + HTML end it "should support html classes for grid class with namespace" do @@ -517,7 +517,6 @@ def param_name end end - describe ".datagrid_form_with" do it "returns namespaced partial if partials options is passed" do rendered_form = subject.datagrid_form_with( @@ -534,16 +533,16 @@ class FormWithGrid < Datagrid::Base end object = FormWithGrid.new(category: "hello") expect(subject.datagrid_form_with(model: object, url: "/grid")).to equal_to_dom(<<~HTML) - + HTML end it "should support html classes for grid class with namespace" do @@ -591,7 +590,6 @@ def param_name end end - describe ".datagrid_row" do let(:grid) do test_report do @@ -734,14 +732,14 @@ def param_name grid = test_report(order: :name, descending: true) do scope { Entry } column(:name) - column(:group_id, class: 'short-column') + column(:group_id, class: "short-column") end silence_deprecator do expect(subject.send(:datagrid_column_classes, grid, :name)).to eq( - "name ordered desc" + "name ordered desc", ) expect(subject.send(:datagrid_column_classes, grid, :group_id)).to eq( - "group_id short-column" + "group_id short-column", ) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4735698b..2322b781 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -108,4 +108,4 @@ def silence_deprecator(&block) # Requires supporting files with custom matchers and macros, etc, # in ./support/ and its subdirectories. -Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f } +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } diff --git a/version-2/find_broken_range_filters.rb b/version-2/find_broken_range_filters.rb index 989643dd..c53fff69 100644 --- a/version-2/find_broken_range_filters.rb +++ b/version-2/find_broken_range_filters.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Important in development to have all classes in memory Rails.application.eager_load!