ActiveAdmin - implement HABTM / multidimensional array in DSL
Asked Answered
S

6

5

In my application everything works fine, but in my Active Admin backend I don't get my user roles displayed on screen.

I have two models "User" and "Roles":

class Role < ActiveRecord::Base
  has_and_belongs_to_many :users, :join_table => :roles_users
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :roles, :join_table => :roles_users
end

I get it to work in the rails console:

ruby-1.9.2-p290 :006 > user.roles
 => [#<Role id: 3, name: "Student">, #<Role id: 2, name: "Supervisor">] 
ruby-1.9.2-p290 :007 > user.roles[0].name
 => "Student" 
ruby-1.9.2-p290 :008 > user.roles[1].name
 => "Supervisor" 

And I tried several ways of implementing this in Active Admin DSL (one of it):

ActiveAdmin.register User do
  index do
    column :email
    column "Role" do |user|
      user.roles.each do |p|
        p.name
      end
    end
  end
end

Could somebody please help me? How do I get it to work in DSL of Active Admin?

Specialism answered 14/9, 2011 at 16:48 Comment(0)
C
13

I haven't tested this myself, but I believe you need to return a string from the block in "column", so something like

column "Role" do |user|
  user.roles.map({ |p| p.name }).join(' ')
end

might work.

Curiel answered 16/9, 2011 at 18:10 Comment(2)
It's working! Thank you!!!!! Thank you so much!!! :) OMG, I can't believe it. It's working :)Specialism
This threw an error for me, but removing the '()' around the map call fixed the problem.Ballance
S
5

That's the working code (in my case):

column "Role" do |user|
  user.roles.map { |p| p.name }.join('<br />').html_safe
end

The Array map function: http://corelib.rubyonrails.org/classes/Array.html#M000427

Specialism answered 18/9, 2011 at 20:9 Comment(0)
G
3

To be able to manipulate associations from the admin, you will need to add an input to the forms block in addition to the code in the index block. You can also add user roles to the show screen inside the show block.

ActiveAdmin.register User do
  index do
    column :email
    column "Role" do |user|
      (user.roles.map{ |p| p.name }).join(' ')
    end
  end

  form do |f|
    f.inputs do
      f.input :email
      f.input :roles # add roles input here
    end
    f.buttons
  end

  show do
    div :class => 'panel' do
      h3 'User Details'
      div :class => 'panel_contents' do
        div :class => 'attributes_table user' do
          table do
            tr do
              th { 'Email' }
              td { user.email }
            end
            tr do
              th { 'Roles' }
              td { (user.roles.map { |p| p.name }).join(' ') }
            end
          end # table
        end # attributes_table
      end # panel_contents
    end # panel
  end # show
end
Galahad answered 5/10, 2011 at 14:43 Comment(3)
if you would have posted this just a week earlier :D By now I already figured it out myself. But thank your for posting it. Let's leave it here for further reference. It might help somebody else :)Specialism
@user930328: I had to customize ActiveAdmin for my first Rails project and this question pointed me in the right direction. I too had to figure out the rest myself and posted it for anybody else who might find it useful, since it's not in ActiveAdmin docs.Galahad
While we are at it, same question on filters: I want to filter for Roles in the sidebar. But since "Roles" doesn't physically exist as attribute in the database, AA doesn't even display it. I already tried to define it as a method in my user model. AA doesn't care about that either. It doesn't show the filter :( Any idea?Specialism
C
1

You could also add links to the items in the list. (of course, this only makes sense if the model you're listing –in this case, "roles"– is also an ActiveAdmin resource)

Example:

column "Role" do |user|
  user.roles.map { |p| link_to p.name admin_role_path}.join(' ,').html_safe
end

Not sure if this applies to your case, but I found it useful.

Crate answered 13/6, 2012 at 2:8 Comment(1)
That did not work for me but found an alternative: the auto_link function. rubydoc.info/github/gregbell/active_admin/ActiveAdmin/…Fley
H
0

This works for me:

column :role do |user|
   user.role.map{ |role| role.name }.join(' ')
end
Haymaker answered 6/4, 2013 at 23:59 Comment(0)
D
0

To link them with auto_link as mentioned in one of the comments above:

column "Role" do |user|
  user.roles.map { |p| auto_link(p) }.join(', ').html_safe
end
Dormant answered 19/4, 2015 at 8:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.