I”ve been asked a couple of times how to dynamically setup the columns displayed by the AS plugin dependant on the permissions of the user, so I though a quick post would be a good idea.
Basically its very simple, you simply define a hash of all the columns you potentially wish to display keyed by the column name, so something like:
@@columns_hash[:user] = ScaffoldColumn.new(..) @@columns_hash[:foo] = ScaffoldColumn.new(:name => 'bar')
Then define a before_filter along the lines of:
before_filter :create_columns,nly => ['table', 'update_table']
Finally all you need to do is write the create_columns method to assign the appropriate columns dependant on the user:
def create_columns
if user.is_administrator
@@scaffold_columns = [ @@columns_hash[:user], @@columns_hash[:foo] ]
else
@@scaffold_columns = [ @@columns_hash[:user] ]
end
end
A bit contrived but you get the idea.
This method should continue working in the upcoming 4.0 version of the plugin (associations, search, all sorts of loveliness in that…..) however I think it will have been refined a bit to get rid of the class variables. But for now, it should solve the problem.










8 Comments
Scott,
First off, thanks for both the nice response, and the plugin…it is making my life much easier.
Second, once you showed this, I found (at least to me) an easier way to do the column filtering….
I went ahead and did the usual:
<pre><code>
@@scaffold_columns = [
AjaxScaffold::ScaffoldColumn.new(...),
AjaxScaffold::ScaffoldColumn.new(...)
]
</code></pre>
for each of the common columns (ones that each user should see), then I did this in the def create_columns:
<pre><code>
def create_columns
if @user.is_admin?
@@scaffold_columns.insert(2,AjaxScaffold::ScaffoldColumn.new(…admin only column)
end
end
</code></pre>
you can use the array insert to put a column before or after any of the ones set previously…(integer after .insert( is the position)
Thanks again for all the hard work!
Hi Jonathon, that looks pretty neat. I suspect there are a few more ways too. All good.
Cheers
Scott.
Hmmm…my thought above works great in development, but once I tried in production mode, it looks like it caches the @@scaffold_columns and goes through create_colums each time, so I end up with lots if repeats of ‘admin’ columns…
any ideas?
Hi Jonathon, ah yes, should of thought of that. I think the hash direction I originally outlined would be your best bet. Then the actual column objects are only instantiated once but you can dynamically assign them on each request. As you completely overriding the @@scaffold_columns array you won’t have this problem.
Cheers
Scott.
Well I’m just starting with ajaxscaffold … My problem is I want show a *few* columns in the grid view and *many* columns in the edit view. I tried the @@scaffold_columns way and I think my problem is related with the previous comments, but I’m also new in Ruby. Can help me, please?
Hi Jorge, to do this you will need to use the @scaffold_columns to define the grid view and create a custom _form.rhtml template for the edit view.
Cheers
Scott.
Thanks a lot: just this was my intuitive guess, but I find for some most "generic": I have some internal fields I need in each table. My feeling is Ajax-Scaffold is very good at "entry level" but it goes difficultd in more complex views: A master/detail form fo example. Well maybe I must wait for AS 4.0
. I’m tried also streamlinned framework for the same, but it seems immature for now for my work. Sorry if all these feelings is my low expertise in RoR, I don’t sure but I’m learning hard
Thansk! (sorry also my limited english)
Hi
I tried implementing this with a controller and table that has:<br>
:suffix => true<br>
On my column hash I get an error:
uninitialized class variable @@columns_hash in TeamController
I have tried naming the hash both columns_hash and users_columns_hash with the same result.
this is the code in the controller.
@@users_columns_hash[:user] = AjaxScaffold::ScaffoldColumn.new(:name => ‘first’, :name => ‘last’)
@@users_columns_hash[:foo] = AjaxScaffold::ScaffoldColumn.new(:name => ‘email’)
I have also tried without the AjaxScaffold:: before ScaffoldColumn and same result.
Assume I am doing something wrong, can you help.
thanks.
Jeff