Skip to content

Instantly share code, notes, and snippets.

@Val
Created October 1, 2012 09:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Val/3810559 to your computer and use it in GitHub Desktop.
Save Val/3810559 to your computer and use it in GitHub Desktop.
Rails template to test list's filters on has_and_belongs_to_many associations
# -*- mode:ruby;indent-tabs-mode:nil;coding:utf-8 -*-
#
# rails_admin test template: (c) 2012 Laurent Vallar <val@zbla.net>
#
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
#
# see:
# http://edgeguides.rubyonrails.org/rails_application_templates.html
# http://m.onkey.org/rails-templates
# https://github.com/RailsApps/rails3-application-templates
#
# see https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md
# for FactoryGirl documentation.
#
# see http://rubydoc.info/github/stympy/faker/master/frames for available fakes
#
# run with:
# rails new test_rails_admin -m rails_admin_sample_template.rb
#
# define proper environment
RAILS_ENV = 'development'
# configure Gemfile
gem 'thin'
gem 'faker'
gem 'factory_girl_rails'
gem 'execjs'
gem 'therubyracer', :platforms => :ruby
gem 'devise'
gem 'rails_admin'
# install needed gems
run 'bundle install'
run 'bundle update'
# generate models
generate :model, 'Book', 'title:string', 'author:references'
generate :model, 'Author', 'name:string'
generate :model, 'Collection', 'label:string'
generate(:migration, 'CreateTableBooksCollections',
'book:references', 'collection:references')
migration = Dir.glob('db/migrate/*_create_table_books_collections.rb').first
remove_file migration
create_file migration do
<<-RUBY
class CreateTableBooksCollections < ActiveRecord::Migration
def up
create_table :books_collections, :id => false do |t|
t.references :book
t.references :collection
end
add_index :books_collections, [ :book_id, :collection_id ], :primary => true
add_index :books_collections, :book_id
add_index :books_collections, :collection_id
end
def down
drop_table :books_collections
end
end
RUBY
end
# configure (author 1-N books) association
inject_into_file('app/models/author.rb',
:before => 'end') do
<<-RUBY
has_many :books
RUBY
end
inject_into_file('app/models/book.rb',
:before => 'end') do
<<-RUBY
# validates_presence_of :author
RUBY
end
# configure (books N-N collections) association
inject_into_file('app/models/book.rb',
:before => 'end') do
<<-RUBY
has_and_belongs_to_many :collections
RUBY
end
inject_into_file('app/models/collection.rb',
:before => 'end') do
<<-RUBY
has_and_belongs_to_many :books
RUBY
end
# install devise for authentication
generate 'devise:install'
generate :devise, 'User'
# create & migrate database (needed before rails_admin installation)
rake 'db:create', :env => RAILS_ENV
rake 'db:migrate', :env => RAILS_ENV
# auto reply for "generate 'rails_admin:install'"
run '/bin/echo -e \'user\nrails_admin\n\' | rails g rails_admin:install'
# disable authentication (devise) in rails_admin
inject_into_file('config/initializers/rails_admin.rb',
:after => '|config|') { "\n config.authenticate_with {}" }
gsub_file('config/initializers/rails_admin.rb',
/(config\.current_user_method \{ current_admin \})/,
'# \1')
# don't view User's model
gsub_file('config/initializers/rails_admin.rb',
/^((.*)(# )(config.excluded_models = )(.*))$/,
"\\1\n\\2\\4[User]")
# change to dynamic title
gsub_file('config/initializers/rails_admin.rb',
/^(\s+)(config.main_app_name = ).*$/, '\1# \2')
gsub_file('config/initializers/rails_admin.rb',
/^(\s+)# (config.main_app_name = Proc.new.*)$/, '\1\2')
# rails_admin needs the asset pipeline
gsub_file('config/application.rb',
/(config.assets.enabled = true)/,
"\\1\n config.assets.initialize_on_precompile = false\n")
# remove id, created_at, updated_at from lists
inject_into_file('config/initializers/rails_admin.rb',
:before => /^end$/) do
<<-RUBY
config.models do
list do
exclude_fields :id, :created_at, :updated_at
end
end
RUBY
end
# configure User's factory
##############################################################################
# remove default string configuration
gsub_file 'test/factories/users.rb', /^.*"MyString".*$/, ''
# configure faked field
inject_into_file('test/factories/users.rb',
:after => ':user do') do
<<-RUBY
email { Faker::Internet.email }
password 'password'
password_confirmation 'password'
RUBY
end
# add population script
create_file('lib/seed_sample_users.rb') do
<<-RUBY
module Seeds
class SampleUsers
def self.run
User.delete_all
FactoryGirl.create(:user)
4.times do |n|
FactoryGirl.create(:user, :email => "user_\#{n+1}@example.org")
end
end
end
end
RUBY
end
# configure Author's factory
##############################################################################
# remove default string configuration
gsub_file 'test/factories/authors.rb', /^.*"MyString".*$/, ''
# configure faked fields
inject_into_file('test/factories/authors.rb',
:after => ':author do') do
<<-RUBY
name { Faker::Name.name }
books []
RUBY
end
# add population script
create_file('lib/seed_sample_authors.rb') do
<<-RUBY
module Seeds
class SampleAuthors
def self.run
Author.delete_all
FactoryGirl.create_list(:author, 17)
end
end
end
RUBY
end
# configure Book's factory
##############################################################################
# remove default string configuration
gsub_file 'test/factories/books.rb', /^.*"MyString".*$/, ''
# configure faked field
inject_into_file('test/factories/books.rb',
:after => ':book do') do
<<-RUBY
title { Faker::Lorem.sentence }
RUBY
end
# add population script
create_file('lib/seed_sample_books.rb') do
<<-RUBY
module Seeds
class SampleBooks
def self.run
Book.delete_all
authors = Author.all
author = nil
29.times do
author = authors.sample
book = FactoryGirl.create(:book, :author_id => author.id)
end
end
end
end
RUBY
end
# configure Collection's factory
##############################################################################
# remove default string configuration
gsub_file 'test/factories/collections.rb', /^.*"MyString".*$/, ''
# configure faked field
inject_into_file('test/factories/collections.rb',
:after => ':collection do') do
<<-RUBY
label { Faker::Lorem.sentence }
books []
RUBY
end
inject_into_file('test/factories/books.rb',
:before => "end\nend") do
<<-RUBY
collections []
RUBY
end
# add population script
create_file('lib/seed_sample_collections.rb') do
<<-RUBY
module Seeds
class SampleCollections
def self.run
Collection.delete_all
books = Book.all
random_books = nil
random_count = nil
4.times do
collection = FactoryGirl.create(:collection)
random_count = Random.rand(1...books.size)
random_books = books.sort_by{ rand }.slice(0...random_count)
random_books.each do |random_book|
collection.books << random_book
end
end
end
end
end
RUBY
end
##############################################################################
# Add helper to see association count and provide direct link to appropriate
# association filter
helper = 'app/helpers/application_helper.rb'
remove_file helper
create_file helper do
<<-RUBY
# -*- mode:ruby;tab-width:2;indent-tabs-mode:nil;coding:utf-8 -*-
# vim: ft=ruby syn=ruby fileencoding=utf-8 sw=2 ts=2 ai eol et si
module ApplicationHelper
ENUM_LIMIT = 5
def self.association_count_link(bindings, klass, asso_key, value_key)
object = bindings[:object]
index = Time.now.to_f.to_s.gsub('.','').slice(6,11).slice(0,5)
object_value = object.send value_key
klass_param = object.class.table_name.singularize
count = object.send(asso_key).count
bindings[:view].
link_to(count.to_s,
bindings[:view].rails_admin.index_path(klass) + '?utf8=✓&f' +
CGI.escape('[' + klass_param + '][' + index +
'][o]') +
'=is&f' +
CGI.escape('[' + klass_param + '][' + index +
'][v]') +
'=' + CGI.escape(object_value) + '&query=',
:target => '_blank', :class => 'pjax')
end
end
RUBY
end
model = 'app/models/author.rb'
inject_into_file(model, :before => /^end$/) do
<<-RUBY
rails_admin do
# Found associations:
configure :books, :has_many_association
# Found columns:
configure :id, :integer
configure :name, :string
configure :created_at, :datetime
configure :updated_at, :datetime
field :id
field :name
field :created_at
field :updated_at
field :books do
searchable [ :title ]
end
list do
field :books do
pretty_value do
ApplicationHelper.association_count_link(bindings, Book,
:books, :name)
end
end
end
end
RUBY
end
model = 'app/models/book.rb'
inject_into_file(model, :before => /^end$/) do
<<-RUBY
rails_admin do
# Found associations:
configure :author, :belongs_to_association
configure :collections, :has_and_belongs_to_many_association
# Found columns:
configure :id, :integer
configure :title, :string
configure :author_id, :integer # Hidden
configure :created_at, :datetime
configure :updated_at, :datetime
configure :author do
searchable [ :name ]
end
configure :collections do
searchable [ :label ]
end
field :id
field :title
field :author
field :collections
field :created_at
field :updated_at
list do
field :collections do
pretty_value do
ApplicationHelper.association_count_link(bindings, Collection,
:collections, :title)
end
end
end
end
RUBY
end
model = 'app/models/collection.rb'
inject_into_file(model, :before => /^end$/) do
<<-RUBY
rails_admin do
# Found associations:
configure :books, :has_and_belongs_to_many_association
# Found columns:
configure :id, :integer
configure :label, :string
configure :created_at, :datetime
configure :updated_at, :datetime
field :id
field :label
field :created_at
field :updated_at
field :books do
searchable [ :title ]
end
list do
field :books do
pretty_value do
ApplicationHelper.association_count_link(bindings, Book,
:books, :label)
end
end
end
end
RUBY
end
##############################################################################
# add global seeding script (for use with rake db:seed)
append_file('db/seeds.rb') do
<<-RUBY
require 'seed_sample_users'
require 'seed_sample_authors'
require 'seed_sample_books'
require 'seed_sample_collections'
Seeds::SampleUsers.run
Seeds::SampleAuthors.run
Seeds::SampleBooks.run
Seeds::SampleCollections.run
RUBY
end
# do last migration
rake 'db:migrate', :env => RAILS_ENV
# seed database
rake 'db:seed', :env => RAILS_ENV
# another way, move static index file and link application root
inside('public') { run 'mv index.html index_orig.html' }
route 'root :to => \'rails_admin::Main#dashboard\''
# cleanup assets
rake 'assets:clean', :env => RAILS_ENV
# remove test.sqlite3 default generated database for Rails templating
remove_file 'db/test.sqlite3'
say 'all done'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment