Skip to content

Commit

Permalink
Delegate missing methods in CSV block to current view context
Browse files Browse the repository at this point in the history
  • Loading branch information
shekibobo committed Jan 31, 2014
1 parent 99da460 commit c4c027e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 14 deletions.
2 changes: 1 addition & 1 deletion app/views/active_admin/resource/index.csv.erb
Expand Up @@ -3,7 +3,7 @@

default = active_admin_application.csv_options
options = default.merge active_admin_config.csv_builder.options
columns = active_admin_config.csv_builder.columns
columns = active_admin_config.csv_builder.render_columns(self)

csv_output = CSV.generate(options) do |csv|
csv << columns.map(&:name)
Expand Down
32 changes: 26 additions & 6 deletions lib/active_admin/csv_builder.rb
Expand Up @@ -17,27 +17,47 @@ class CSVBuilder
# The CSVBuilder's columns would be Id followed by this
# resource's content columns
def self.default_for_resource(resource)
new(resource: resource).tap do |csv_builder|
csv_builder.column(:id)
new(resource: resource) do
column(:id)
resource.content_columns.each do |content_column|
csv_builder.column(content_column.name.to_sym)
column(content_column.name.to_sym)
end
end
end

attr_reader :columns, :options
attr_reader :columns, :options, :view_context

def initialize(options={}, &block)
@resource = options.delete(:resource)
@columns, @options = [], options
instance_exec &block if block_given?
@columns, @options, @block = [], options, block
end

# Add a column
def column(name, &block)
@columns << Column.new(name, @resource, block)
end

# Runs the `csv` dsl block and render our columns
# Called from `index.csv.erb`, which passes in the current view context.
# This provides methods that could be called in the views to be called within
# the CSV block. Any method not defined on the CSV builder will instead be
# sent to the view context in order to emulate the capabilities of the `index`
# DSL.
def render_columns(view_context = nil)
@view_context = view_context
@columns = [] # we want to re-render these every instance
instance_eval &@block if @block.present?
columns
end

def method_missing(method, *args, &block)
if @view_context.respond_to?(method)
@view_context.send(method, *args, &block)
else
super
end
end

class Column
attr_reader :name, :data

Expand Down
29 changes: 23 additions & 6 deletions spec/unit/csv_builder_spec.rb
Expand Up @@ -3,7 +3,7 @@
describe ActiveAdmin::CSVBuilder do

describe '.default_for_resource using Post' do
let(:csv_builder) { ActiveAdmin::CSVBuilder.default_for_resource(Post) }
let(:csv_builder) { ActiveAdmin::CSVBuilder.default_for_resource(Post).tap(&:render_columns) }

it 'returns a default csv_builder for Post' do
expect(csv_builder).to be_a(ActiveAdmin::CSVBuilder)
Expand Down Expand Up @@ -37,7 +37,7 @@
end

context 'when empty' do
let(:builder){ ActiveAdmin::CSVBuilder.new }
let(:builder){ ActiveAdmin::CSVBuilder.new.tap(&:render_columns) }

it "should have no columns" do
expect(builder.columns).to eq []
Expand All @@ -48,7 +48,7 @@
let(:builder) do
ActiveAdmin::CSVBuilder.new do
column :title
end
end.tap(&:render_columns)
end

it "should have one column" do
Expand All @@ -74,7 +74,7 @@
column "My title" do
# nothing
end
end
end.tap(&:render_columns)
end

it "should have one column" do
Expand All @@ -96,7 +96,7 @@

context "with a separator" do
let(:builder) do
ActiveAdmin::CSVBuilder.new :col_sep => ";"
ActiveAdmin::CSVBuilder.new(:col_sep => ";").tap(&:render_columns)
end

it "should have proper separator" do
Expand All @@ -106,12 +106,29 @@

context "with csv_options" do
let(:builder) do
ActiveAdmin::CSVBuilder.new :force_quotes => true
ActiveAdmin::CSVBuilder.new(:force_quotes => true).tap(&:render_columns)
end

it "should have proper separator" do
expect(builder.options).to eq({:force_quotes => true})
end
end

context "with access to the controller" do
let(:dummy_view_context) { double(controller: dummy_controller) }
let(:dummy_controller) { double(names: %w(title summary updated_at created_at))}
let(:builder) do
ActiveAdmin::CSVBuilder.new do
column "id"
controller.names.each do |name|
column(name)
end
end.tap{|b| b.render_columns(dummy_view_context)}
end

it "should render columns provided by the controller" do
expect(builder.columns.map(&:data)).to match_array([:id, :title, :summary, :updated_at, :created_at])
end
end

end
2 changes: 1 addition & 1 deletion spec/unit/resource_spec.rb
Expand Up @@ -196,7 +196,7 @@ def config(options = {})
describe "#csv_builder" do
context "when no csv builder set" do
it "should return a default column builder with id and content columns" do
expect(config.csv_builder.columns.size).to eq Category.content_columns.size + 1
expect(config.csv_builder.render_columns.size).to eq Category.content_columns.size + 1
end
end

Expand Down

0 comments on commit c4c027e

Please sign in to comment.