Skip to content

Commit

Permalink
Add DSL for association eager-loading
Browse files Browse the repository at this point in the history
Closes #1325, Closes #1342, Closes #1434, Closes #2649, Refs. #2682
  • Loading branch information
mshibuya committed Sep 24, 2016
1 parent b2bae25 commit b92a4d1
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

[Full Changelog](https://github.com/sferik/rails_admin/compare/v1.0.0...HEAD)

### Added
- DSL for association eager-loading([#1325](https://github.com/sferik/rails_admin/issues/1325), [#1342](https://github.com/sferik/rails_admin/issues/1342))


## [1.0.0](https://github.com/sferik/rails_admin/tree/v1.0.0) - 2016-09-19

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/rails_admin/main_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def check_for_cancel
end

def get_collection(model_config, scope, pagination)
associations = model_config.list.fields.select { |f| f.type == :belongs_to_association && !f.polymorphic? }.collect { |f| f.association.name }
associations = model_config.list.fields.select { |f| f.try(:eager_load?) }.collect { |f| f.association.name }
options = {}
options = options.merge(page: (params[Kaminari.config.param_name] || 1).to_i, per: (params[:per] || model_config.list.items_per_page)) if pagination
options = options.merge(include: associations) unless associations.blank?
Expand Down
4 changes: 4 additions & 0 deletions lib/rails_admin/config/fields/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def association
association.foreign_key_nullable?
end

register_instance_option :eager_load? do
!!searchable
end

# Reader for the association's child model's configuration
def associated_model_config
@associated_model_config ||= RailsAdmin.config(association.klass)
Expand Down
4 changes: 4 additions & 0 deletions lib/rails_admin/config/fields/types/belongs_to_association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class BelongsToAssociation < RailsAdmin::Config::Fields::Association
true
end

register_instance_option :eager_load? do
true
end

def selected_id
bindings[:object].send(foreign_key)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class PolymorphicAssociation < RailsAdmin::Config::Fields::Types::BelongsToAssoc
[children_fields]
end

register_instance_option :eager_load? do
false
end

def associated_collection(type)
return [] if type.blank?
config = RailsAdmin.config(type)
Expand Down
21 changes: 21 additions & 0 deletions spec/controllers/rails_admin/main_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,27 @@ def get(action, params)
end
end

describe '#get_collection' do
before do
@team = FactoryGirl.create(:team)
controller.params = {model_name: 'teams'}
RailsAdmin.config Team do
field :players do
eager_load true
end
end
@model_config = RailsAdmin.config(Team)
end

it 'performs eager-loading for an association field with `eagar_load true`' do
scope = double('scope')
abstract_model = @model_config.abstract_model
allow(@model_config).to receive(:abstract_model).and_return(abstract_model)
expect(abstract_model).to receive(:all).with(hash_including(include: [:players]), scope).once
controller.send(:get_collection, @model_config, scope, false)
end
end

describe 'index' do
it "uses source association's primary key with :compact, not target model's default primary key", skip_mongoid: true do
class TeamWithNumberedPlayers < Team
Expand Down
18 changes: 18 additions & 0 deletions spec/integration/basic/list/rails_admin_basic_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
FactoryGirl.create(:player, retired: false, injured: true, team: @teams[1]),
FactoryGirl.create(:player, retired: false, injured: false, team: @teams[1]),
]
@comment = FactoryGirl.create(:comment, commentable: @players[2])
end

it 'allows to query on any attribute' do
Expand Down Expand Up @@ -270,6 +271,23 @@
is_expected.to have_no_content(@players[3].name)
end

it 'allows to search a has_many attribute over the target table' do
RailsAdmin.config Player do
list do
field PK_COLUMN
field :name
field :comments do
searchable :content
end
end
end
visit index_path(model_name: 'player', f: {comments: {'1' => {v: @comment.content}}})
is_expected.to have_no_content(@players[0].name)
is_expected.to have_no_content(@players[1].name)
is_expected.to have_content(@players[2].name)
is_expected.to have_no_content(@players[3].name)
end

it 'displays base filters when no filters are present in the params' do
RailsAdmin.config Player do
list { filters([:name, :team]) }
Expand Down

1 comment on commit b92a4d1

@vergenzt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mshibuya, would you mind going ahead and releasing this commit into a version? :) I'm really itching to use the eager loading DSL and would love to not have to depend on a git commit.

Please # to comment.