Search code examples
ruby-on-railsrubyactivescaffold

Helper column override in ruby-on-rails


I have ruby-on-rails app with activescaffold to build GUI based on database structure. Users have roles, each role is a set of rights. Each right is a combination of controller and action which user is permitted to perform in this controller or not.

# DATABASE!
create_table :rights do |t|
  t.column :controller, :string, :limit => 32, :null => false
  t.column :action, :string, :limit => 32, :null => false
end

create_table :rights_roles, :id => false do |t|
  t.column :right_id,      :integer
  t.column :role_id,       :integer
end

create_table :roles do |t|
  t.column :name, :string, :limit => 32, :null => false
end

#MODELS!
class Role < ActiveRecord::Base
  has_and_belongs_to_many :rights

class Right < ActiveRecord::Base
  has_and_belongs_to_many :roles

# ROLE CONTROLLER!
class RoleController < ApplicationController
  active_scaffold :role do |config|
    config.columns = Array[:name, :rights]    
    config.columns[:rights].form_ui = :select

I currently have following edit window for roles which is inconvenient (options are not structured. There will be much more actions, so it would be dreadful):

http://postimage.org/image/4e8ukk2px/

I want to create a helper method like this:

module RoleHelper
  def rights_form_column (record, input_name) 
    ...
  end
end

This is needed to define the form which will specify input method for "rights" column. But I don't know how to write it. Desirable form would be following:

  administration
    action1(checkbox)
    action2(checkbox)
  configuration
    action1(checkbox)
    ...

I know that activescaffold is old, but I have to use it... Please help!


Solution

  • Finally i found the solution. This works good for me =)

    require 'set'
    
    module RoleHelper
      def rights_form_column (record, input_name)
        selected_ids = [].to_set
        record.rights.each do |r|
          selected_ids.add(r.id)
        end
    
    html = '<table style="margin-top:-25; margin-left:112">'
    html << '<tr>'
    html << '<td>'
    html << '<ul style="list-style-type:none">'
    Right.find(:all, :group => :controller).each do |right|
      unless Right::CONFIGURATION_CONTROLLERS.include?(right.controller) then
        html << '<li>'
        html << "<label>#{right.controller.titleize}:</label>"
    
        html << '<ul style="list-style-type:none">'
        Right.find(:all, :conditions => ["controller = ?", right.controller]).each do |r|
          html << '<li>'
          this_name = "#{input_name}[#{r.id}][id]"
          html << check_box_tag(this_name, r.id, selected_ids.include?(r.id))
          html << "<label for='#{this_name}'>"
          html << r.action.titleize
          html << '</label>'
          html << '</li>'
        end      
        html << '</ul>'
        html << '</li>'
      end
    end
    
    html << '<li>' # configuration section
    html << "<label>Configuration:</label>"
    html << '<ul style="list-style-type:none">'
    
    Right.find(:all, :group => :controller).each do |right|
      if Right::CONFIGURATION_CONTROLLERS.include?(right.controller) then
        Right.find(:all, :conditions => ["controller = ?", right.controller]).each do |r|
          html << '<li>'
          this_name = "#{input_name}[#{r.id}][id]"
          html << check_box_tag(this_name, r.id, selected_ids.include?(r.id))
          html << "<label for='#{this_name}'>"
          html << r.controller.titleize + " edit"
    
    
      html << '</label>'
              html << '</li>'
            end      
          end
        end
    
    html << '</ul>'
    html << '</li>'
    html << '</ul>'
    html << '</td>'
    html << '</tr>'
    html << '</table>'
    html
      end
    end
    

    Dunno why StackOverflow chose such a strange code formatting