Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to "undecorate" resource for forms #2085

Merged
merged 1 commit into from
Apr 10, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 9 additions & 27 deletions docs/11-decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,32 +53,14 @@ Then the following is possible

Note that the resource proveded to form_for also gets decorated.

In most cases this will work as expected. However, it can have some unexpected
results. Here's an example gotcha:

```ruby
class UserDecorator < Draper::Base
decorates :user

def self.status_options_for_select
User.status_options.map { |s| [s.humanize, s] }
end

def status
model.status.titleize
end
end

ActiveAdmin.register User do
form do
f.inputs do
f.input :status, collection: UserDecorator.status_options_for_select
end
end
end
```
In most cases this will work as expected. However, it is possible to disable
automatic decoration in the form with the `decorate` option:

ActiveAdmin.register Post do
decorate_with PostDecorator

In this example, `f.object.status` now returns "Submitted", which does not match
the actual status option: "submitted". Because of this, the `<select>` will not
have the correct status selected.
form decorate: false do
# ...
end
end

7 changes: 6 additions & 1 deletion lib/active_admin/view_helpers/form_helper.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
module ActiveAdmin
module ViewHelpers
module FormHelper

def active_admin_form_for(resource, options = {}, &block)
options = Marshal.load( Marshal.dump(options) )
options[:builder] ||= ActiveAdmin::FormBuilder

if ! options.fetch(:decorate, true)
resource = resource.model
end

semantic_form_for resource, options, &block
end

Expand Down
38 changes: 36 additions & 2 deletions spec/unit/view_helpers/form_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
require 'spec_helper'

describe ActiveAdmin::ViewHelpers::FormHelper do

describe '.active_admin_form_for' do
let(:view) { action_view }
let(:resource) { stub('resource') }
let(:default_options) { { builder: ActiveAdmin::FormBuilder } }

it 'calls semantic_form_for with the ActiveAdmin form builder' do
view.should_receive(:semantic_form_for).with(resource, builder: ActiveAdmin::FormBuilder)
view.active_admin_form_for(resource)
end

it 'allows the form builder to be customized' do
# We can't use a stub here because options gets marshalled, and a new
# instance built. Any constant will work.
custom_builder = Object
view.should_receive(:semantic_form_for).with(resource, builder: custom_builder)
view.active_admin_form_for(resource, builder: custom_builder)
end

context 'with a decorated resource' do
let(:decorated) { stub('decorated_resource', model: resource) }

it 'can disable automatic decoration' do
view.should_receive(:semantic_form_for).with(resource, default_options.merge(decorate: false))
view.active_admin_form_for(decorated, decorate: false)
end

it 'can enable automatic decoration' do
view.should_receive(:semantic_form_for).with(decorated, default_options.merge(decorate: true))
view.active_admin_form_for(decorated, decorate: true)
end
end
end

describe ".hidden_field_tags_for" do
let(:view) { action_view }

it "should render hidden field tags for params" do
view.hidden_field_tags_for(:scope => "All", :filter => "None").should ==
view.hidden_field_tags_for(:scope => "All", :filter => "None").should ==
%{<input id="hidden_active_admin_scope" name="scope" type="hidden" value="All" />\n<input id="hidden_active_admin_filter" name="filter" type="hidden" value="None" />}
end

Expand All @@ -14,7 +48,7 @@
end

it "should filter out the field passed via the option :except" do
view.hidden_field_tags_for({:scope => "All", :filter => "None"}, :except => :filter).should ==
view.hidden_field_tags_for({:scope => "All", :filter => "None"}, :except => :filter).should ==
%{<input id="hidden_active_admin_scope" name="scope" type="hidden" value="All" />}
end
end
Expand Down