Monday, May 29, 2006

Beautify Fixtures (Ruby on Rails)

After generating fixtures from my development database (you can read about it here) I decided to make them nice.

Up to now, for example, Permissions were labelled permission_001 and so on. And that is quite counter-intuitive. A good convention to label permissions would be controller_action. For example:

user_new: 
action: new 
id: 19 
controller: user 

The same applies to roles (you can label them with their name) and permissions_roles (you can build the name from their associated role and permission names). This is what my small script does. It is a rake task.
desc "Labels Roles, Permissions and PermissionsRoles after their value so that
the fixture becomes more readable. You can specify the DIR where fixtures we want to modify are.

require 'yaml' 
class Hash 
    def find_item(key, value, default=nil) 
        each do |k, v| 
            return k if (v[key] == value) || (v[key] == value.to_i) 
        end 
        default 
    end 
end 

task :beautify_fixtures => :environment do 
    dir = ENV['DIR'] || "#{RAILS_ROOT}/test/fixtures" 
    db   = ENV['DB']   || 'development' 
    File.cp "#{dir}/roles.yml",             "#{dir}/roles.bkp.yml" 
    File.cp "#{dir}/permissions.yml",       "#{dir}/permissions.bkp.yml" 
    File.cp "#{dir}/permissions_roles.yml", "#{dir}/permissions_roles.bkp.yml" 
    permissions = YAML.load_file("#{dir}/permissions.bkp.yml") 
    roles = YAML.load_file("#{dir}/roles.bkp.yml") 
    File.open("#{dir}/permissions.yml", 'w') do |file| 
        permissions.each do |k, v| 
            controller = v['controller'] 
            action = v['action'] 
            file.write "#{controller}_#{action}:n" 
            v.each {|key, value| file.write "  #{key}: #{value}n"} 
        end 
    end 
    File.open("#{dir}/roles.yml", 'w') do |file| 
        roles.each do |k, record| 
            file.write "#{record['name'].downcase}:n" 
            record.each {|key, value| file.write "  #{key}: #{value}n"} 
        end 
    end 

    permissions = YAML.load_file("#{dir}/permissions.yml") 
    roles = YAML.load_file("#{dir}/roles.yml") 
    prs = YAML.load_file("#{dir}/permissions_roles.bkp.yml") 
    
    File.open("#{dir}/permissions_roles.yml", 'w') do |file| 
        prs.each do |k, record| 
            permission = permissions.find_item('id', record['permission_id']) 
            role = roles.find_item('id', record['role_id']) 
            file.write "#{role}_#{permission}n" 
            record.each {|key, value| file.write "  #{key}: #{value}n"} 
        end 
    end 
end 

You can find a downloadable version here [BROKEN!]

No comments: