I’m currently building yet another CMS, this time with Sinatra. And i was having a lot of code duplication in my controllers where i created the usual CRUD (Create Read Update Delete) actions.
Here’s how it works: I have this base class (abridged for this post) for all my controllers, named “Joiedmin”.
class AdminController < Sinatra::Base
def self.crud(route_prefix, singular_name)
self.class_eval <<EVAL
get '#{route_prefix}' do
@#{singular_name.pluralize} = #{singular_name.pluralize.classify}.all
haml :index
end
get '#{route_prefix}new' do
@#{singular_name} = #{singular_name.pluralize.classify}.new
haml :new
end
post '#{route_prefix}new' do
@#{singular_name} = #{singular_name.pluralize.classify}.new(params[:#{singular_name}])
if @#{singular_name}.save
redirect '/admin#{route_prefix}#{singular_name.pluralize}'
else
haml :new
end
end
get '#{route_prefix}edit/:id' do
@#{singular_name} = #{singular_name.pluralize.classify}.find params[:id]
haml :edit
end
put '#{route_prefix}edit/:id' do
@#{singular_name} = #{singular_name.pluralize.classify}.find params[:id]
if @#{singular_name}.update_attributes(params[:#{singular_name}])
redirect '/admin#{route_prefix}#{singular_name.pluralize}'
else
haml :edit
end
end
delete '#{route_prefix}delete/:id' do
#{singular_name.pluralize.classify}.find(params[:id]).destroy
redirect '/admin#{route_prefix}#{singular_name.pluralize}'
end
EVAL
end
end
(Note that for the “pluralize” and “classify” methods to work, you’ll need to include “activesupport” in your Gemfile.)
And in each of my controller’s classes, all i have to do is just calling the crud method like so:
class Acclaims < Joiedmin::AdminController
crud '/', 'acclaim'
# more controller stuff...
end
I found the class_eval trick in this thread: http://stackoverflow.com/questions/973728/self-class-eval-def-def.