Skip to content

Commit

Permalink
Provide has_one id setters/getters, eliminating the need for explicit…
Browse files Browse the repository at this point in the history
…ly define them

Closes #2625
  • Loading branch information
mshibuya committed Oct 25, 2021
1 parent af88091 commit 39e2cc3
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 20 deletions.
18 changes: 18 additions & 0 deletions lib/rails_admin/adapters/active_record/object_extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@ module RailsAdmin
module Adapters
module ActiveRecord
module ObjectExtension
def self.extended(object)
object.class.reflect_on_all_associations.each do |association|
association = Association.new(association, object.class)
case association.type
when :has_one
object.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{association.name}_id
self.#{association.name}&.id
end
def #{association.name}_id=(item_id)
self.#{association.name} = #{association.klass}.find_by_id(item_id)
end
RUBY
end
end
end

def assign_attributes(attributes)
super if attributes
end
Expand Down
5 changes: 5 additions & 0 deletions lib/rails_admin/adapters/mongoid/object_extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ def self.extended(object)
send(name)&.save
end
end
object.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{name}_id=(item_id)
self.#{name} = (#{association.klass}.find(item_id) rescue nil)
end
RUBY
end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/rails_admin/config/fields/types/has_one_association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ class HasOneAssociation < RailsAdmin::Config::Fields::Association
(o = value) && o.send(associated_model_config.object_label_method)
end

def editable?
(nested_form || abstract_model.model.new.respond_to?("#{name}_id=")) && super
end

def selected_id
value.try :id
end
Expand Down
8 changes: 0 additions & 8 deletions spec/dummy_app/app/active_record/player.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,4 @@ class Player < ActiveRecord::Base
scope :rails_admin_search, ->(query) { where(name: query.reverse) }

def destroy_hook; end

def draft_id
draft.try :id
end

def draft_id=(id)
self.draft = Draft.find_by_id(id)
end
end
8 changes: 0 additions & 8 deletions spec/dummy_app/app/mongoid/player.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,4 @@ class Player
scope :rails_admin_search, ->(query) { where(name: query.reverse) }

def destroy_hook; end

def draft_id
draft.try :id
end

def draft_id=(id)
self.draft = Draft.where(_id: id).first
end
end
48 changes: 48 additions & 0 deletions spec/rails_admin/adapters/active_record/object_extension_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,52 @@
expect(object.assign_attributes(nil)).to be nil
end
end

describe 'has_one association' do
let(:draft) { FactoryBot.create(:draft) }
let(:player) { FactoryBot.build(:player).extend(RailsAdmin::Adapters::ActiveRecord::ObjectExtension) }
before do
class PlayerWithAutoSave < Player
has_one :draft, inverse_of: :player, foreign_key: :player_id, autosave: true
end
end

it 'provides id getter' do
player.draft = draft
expect(player.draft_id).to eq draft.id
end

context 'on create' do
before do
player.draft_id = draft.id
expect(player.draft).to receive(:save).once.and_call_original
player.save
end

it 'persists associated documents changes on save' do
expect(player.reload.draft).to eq draft
end
end

context 'on update' do
let(:player) { FactoryBot.create(:player).extend(RailsAdmin::Adapters::ActiveRecord::ObjectExtension) }
before do
player.draft_id = draft.id
end

it 'persists associated documents changes on assignment' do
expect(player.reload.draft).to eq draft
end
end

context 'with explicit id setter' do
let(:user) { ManagingUser.create(FactoryBot.attributes_for(:user)) }
let(:team) { ManagedTeam.create(FactoryBot.attributes_for(:team)) }

it 'works without issues' do
user.team_id = team.id
expect(user.reload.team).to eq team
end
end
end
end
10 changes: 10 additions & 0 deletions spec/rails_admin/adapters/mongoid/object_extension_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,15 @@ class PlayerWithAutoSave < Player
end
end
end

context 'with explicit id setter' do
let(:user) { ManagingUser.create(FactoryBot.attributes_for(:user)) }
let(:team) { ManagedTeam.create(FactoryBot.attributes_for(:team)) }

it 'works without issues' do
user.team_id = team.id
expect(user.reload.team).to eq team
end
end
end
end

0 comments on commit 39e2cc3

Please sign in to comment.