Created
October 1, 2012 09:36
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- mode:ruby;indent-tabs-mode:nil;coding:utf-8 -*- | |
# | |
# rails_admin test template: (c) 2012 Laurent Vallar <[email protected]> | |
# | |
# 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