I have a rather complicated (having a lot of attributes and methods) model on which I'd like to do a specific view in ActiveAdmin.
I did this for the view, works like a charm.
index do
column :status
column "Complex data" do |my_object|
my_object.compute_complex_data
end
[...]
end
I'd like to have the same thing in my exports (mainly CSV, but why not XML or JSON). However, by default, I'm going to have my resource exported, and not the column that I see.
One option is of course doing the exact same thing...
csv do
column :status
column "Complex data" do |my_object|
my_object.compute_complex_data
end
[...]
end
But I'm clearly copy/pasting code, and I don't like this option.
Is there a way to do the same thing while being DRY (Don't Repeat Yourself)?
I tried to defined my columns in a lambda without success.
common_columns = lambda do
column :status [...]
end
csv do
common_columns.call
end
CodePudding user response:
Well, DRY is not a law, it is just a recommendation. According to Sandy Metz, for example, "...duplication is far cheaper than the wrong abstraction".
In fact, in these cases you deal with very different views that cannot be the same in principle (for example, web view contains action buttons/links while exports are static). Yes, they could share some of the columns, but is there any good abstraction for this subset? Personally, I don't see any. So I would most probably stay with the explicit definitions - they cause the minimum confusion. But if you still insist...
You can do smth like the following:
shared_columns = ->(view) {
view.column :status
view.column "Complex data" do |my_object|
my_object.compute_complex_data
end
# ...
}
index do
shared_columns.call(self)
actions
end
csv do
shared_columns.call(self)
end
and it should work in general. But again, I think this is an example of blind following a buzzword, this is not a good abstraction so I would most probably avoid such a trick in favor of explicitness.