Skip to content

Commit 75504d0

Browse files
committed
Prepopulate modal foreign keys regardless of inverse_of and only for has_one and has_many
Fixes #2585
1 parent 48665ec commit 75504d0

9 files changed

Lines changed: 38 additions & 51 deletions

File tree

app/views/rails_admin/main/_form_filtering_multiselect.html.erb

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
<%
2-
related_id = params[:associations] && params[:associations][field.name.to_s]
32
config = field.associated_model_config
43
source_abstract_model = RailsAdmin.config(form.object.class).abstract_model
54

6-
if form.object.new_record? && related_id.present? && related_id != 'new'
7-
selected = [config.abstract_model.get(related_id)]
8-
else
9-
selected = form.object.send(field.name)
10-
end
5+
selected = form.object.send(field.name)
116
selected_ids = selected.map{|s| s.send(field.associated_primary_key)}
127

138
current_action = params[:action].in?(['create', 'new']) ? 'create' : 'update'
@@ -43,7 +38,6 @@
4338
<% selected_ids = (hdv = field.form_default_value).nil? ? selected_ids : hdv %>
4439
<%= form.select field.method_name, collection, { selected: selected_ids, object: form.object }, field.html_attributes.reverse_merge({data: { filteringmultiselect: true, options: js_data.to_json }, multiple: true}) %>
4540
<% if authorized?(:new, config.abstract_model) && field.inline_add %>
46-
<% path_hash = { model_name: config.abstract_model.to_param, modal: true } %>
47-
<% path_hash.merge!({ associations: { field.inverse_of => (form.object.persisted? ? form.object.id : 'new') } }) if field.inverse_of %>
41+
<% path_hash = { model_name: config.abstract_model.to_param, modal: true }.merge!(field.associated_prepopulate_params) %>
4842
<%= link_to "<i class=\"fas fa-plus\"></i> ".html_safe + wording_for(:link, :new, config.abstract_model), '#', data: { link: new_path(path_hash) }, class: "create btn btn-info", style: 'margin-left:10px' %>
4943
<% end %>

app/views/rails_admin/main/_form_filtering_select.html.erb

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
11
<%
22
config = field.associated_model_config
3-
related_id = params[:associations] && params[:associations][field.name.to_s]
43
source_abstract_model = RailsAdmin.config(form.object.class).abstract_model
54

6-
if form.object.new_record? && related_id.present? && related_id != 'new'
7-
selected = config.abstract_model.get(related_id)
8-
selected_id = selected.send(field.associated_primary_key)
9-
selected_name = selected.send(field.associated_object_label_method)
10-
else
11-
selected_id = field.selected_id
12-
selected_name = field.formatted_value
13-
end
14-
155
current_action = params[:action].in?(['create', 'new']) ? 'create' : 'update'
166

177
edit_url = authorized?(:edit, config.abstract_model) ? edit_path(model_name: config.abstract_model.to_param, modal: true, id: '__ID__') : ''
188

199
xhr = !field.associated_collection_cache_all
2010

21-
collection = xhr ? [[selected_name, selected_id]] : controller.list_entries(config, :index, field.associated_collection_scope, false).map { |o| [o.send(field.associated_object_label_method), o.send(field.associated_primary_key)] }
11+
collection = xhr ? [[field.formatted_value, field.selected_id]] : controller.list_entries(config, :index, field.associated_collection_scope, false).map { |o| [o.send(field.associated_object_label_method), o.send(field.associated_primary_key)] }
2212

2313
js_data = {
2414
xhr: xhr,
2515
remote_source: index_path(config.abstract_model.to_param, source_object_id: form.object.id, source_abstract_model: source_abstract_model.to_param, associated_collection: field.name, current_action: current_action, compact: true)
2616
}
2717
%>
2818

29-
<% selected_id = (hdv = field.form_default_value).nil? ? selected_id : hdv %>
19+
<% selected_id = (hdv = field.form_default_value).nil? ? field.selected_id : hdv %>
3020
<%= form.select field.method_name, collection, { selected: selected_id, include_blank: true }, field.html_attributes.reverse_merge({ data: { filteringselect: true, options: js_data.to_json }, placeholder: t('admin.misc.search'), style: "float: left" }) %>
3121
<% if authorized?(:new, config.abstract_model) && field.inline_add %>
32-
<% path_hash = { model_name: config.abstract_model.to_param, modal: true } %>
33-
<% path_hash.merge!({ associations: { field.inverse_of => (form.object.persisted? ? form.object.id : 'new') } }) if field.inverse_of %>
22+
<% path_hash = { model_name: config.abstract_model.to_param, modal: true }.merge!(field.associated_prepopulate_params) %>
3423
<%= link_to "<i class=\"fas fa-plus\"></i> ".html_safe + wording_for(:link, :new, config.abstract_model), '#', data: { link: new_path(path_hash) }, class: "btn btn-info create", style: 'margin-left:10px' %>
3524
<% end %>
3625
<% if edit_url.present? && field.inline_edit %>

lib/rails_admin/config/fields/association.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ def associated_primary_key
8989
association.primary_key
9090
end
9191

92+
# Returns params which are to be set in modals
93+
def associated_prepopulate_params
94+
{}
95+
end
96+
9297
# Reader whether this is a polymorphic association
9398
def polymorphic?
9499
association.polymorphic?

lib/rails_admin/config/fields/types/has_many_association.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def method_name
2525
def errors
2626
bindings[:object].errors[name]
2727
end
28+
29+
def associated_prepopulate_params
30+
{associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}
31+
end
2832
end
2933
end
3034
end

lib/rails_admin/config/fields/types/has_one_association.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ def method_name
2828
def multiple?
2929
false
3030
end
31+
32+
def associated_prepopulate_params
33+
{associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}
34+
end
3135
end
3236
end
3337
end

spec/integration/actions/new_spec.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,16 @@
4444
expect(page).to have_css('input[value=Sam]')
4545
end
4646

47-
it 'prepropulates belongs to relationships' do
48-
@team = FactoryBot.create :team, name: 'belongs_to association prepopulated'
49-
visit new_path(model_name: 'player', associations: {team: @team.id})
50-
expect(page).to have_css("select#player_team_id option[selected='selected'][value='#{@team.id}']")
47+
it 'prepropulates has_one relationships' do
48+
@draft = FactoryBot.create :draft
49+
@player = FactoryBot.create :player, name: 'has_one association prepopulated'
50+
visit new_path(model_name: 'player', player: {draft_id: @draft.id})
51+
expect(page).to have_css("select#player_draft_id option[selected='selected'][value='#{@draft.id}']")
5152
end
5253

5354
it 'prepropulates has_many relationships' do
5455
@player = FactoryBot.create :player, name: 'has_many association prepopulated'
55-
visit new_path(model_name: 'team', associations: {players: @player.id})
56+
visit new_path(model_name: 'team', team: {player_ids: [@player.id]})
5657
expect(page).to have_css("select#team_player_ids option[selected='selected'][value='#{@player.id}']")
5758
end
5859
end

spec/integration/fields/belongs_to_association_spec.rb

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,10 @@
33
RSpec.describe 'BelongsToAssociation field', type: :request do
44
subject { page }
55

6-
describe 'with inverse_of option' do
7-
it 'adds a related id to the belongs_to create team link' do
8-
@player = FactoryBot.create :player
9-
visit edit_path(model_name: 'player', id: @player.id)
10-
is_expected.to have_selector("a[data-link='/admin/team/new?associations%5Bplayers%5D=#{@player.id}&modal=true']")
11-
end
12-
13-
it 'adds a related id to the has_many create team link' do
14-
@team = FactoryBot.create :team
15-
visit edit_path(model_name: 'team', id: @team.id)
16-
is_expected.to have_selector("a[data-link='/admin/player/new?associations%5Bteam%5D=#{@team.id}&modal=true']")
17-
end
6+
it 'does not add a related id to the belongs_to create team link' do
7+
@player = FactoryBot.create :player
8+
visit edit_path(model_name: 'player', id: @player.id)
9+
is_expected.to have_selector("a[data-link='/admin/team/new?modal=true']")
1810
end
1911

2012
describe 'on create' do

spec/integration/fields/has_many_association_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
RSpec.describe 'HasManyAssociation field', type: :request do
44
subject { page }
55

6+
it 'adds a related id to the has_many create team link' do
7+
@team = FactoryBot.create :team
8+
visit edit_path(model_name: 'team', id: @team.id)
9+
is_expected.to have_selector("a[data-link='/admin/player/new?modal=true&player%5Bteam_id%5D=#{@team.id}']")
10+
end
11+
612
context 'when an association is readonly' do
713
it 'is not editable' do
814
@league = FactoryBot.create :league

spec/integration/fields/has_one_association_spec.rb

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,10 @@
33
RSpec.describe 'HasOneAssociation field', type: :request do
44
subject { page }
55

6-
describe 'with inverse_of option' do
7-
it 'adds a related id to the belongs_to create team link' do
8-
@player = FactoryBot.create :player
9-
visit edit_path(model_name: 'player', id: @player.id)
10-
is_expected.to have_selector("a[data-link='/admin/team/new?associations%5Bplayers%5D=#{@player.id}&modal=true']")
11-
end
12-
13-
it 'adds a related id to the has_many create team link' do
14-
@team = FactoryBot.create :team
15-
visit edit_path(model_name: 'team', id: @team.id)
16-
is_expected.to have_selector("a[data-link='/admin/player/new?associations%5Bteam%5D=#{@team.id}&modal=true']")
17-
end
6+
it 'adds a related id to the has_one create draft link' do
7+
@player = FactoryBot.create :player
8+
visit edit_path(model_name: 'player', id: @player.id)
9+
is_expected.to have_selector("a[data-link='/admin/draft/new?draft%5Bplayer_id%5D=#{@player.id}&modal=true']")
1810
end
1911

2012
context 'on create' do

0 commit comments

Comments
 (0)