Hey Guys, I'm writing a custom Generator(named shcaffold) in Rails 3.0.3, and I'd like it to generate an active_record model(and migration) based on the first argument passed into it(the model's name).
However, I'm getting this error when I run the command:
$ rails g shcaffold someclass
error active_record [not found]
Here's my generator definition, stored in lib/generators/shcaffold/shcaffold_generator.rb:
class ShcaffoldGenerator < Rails::Generators::NamedBase
include Rails::Generators::ResourceHelpers
source_root File.expand_path('../templates', __FILE__)
# Run Other Generators
hook_for :model, :in => :rails, :required => true
end
I'm defining the orm in my app's application.rb:
config.generators do |g|
g.orm :active_record
g.template_engine :erb
g.test_framework :test_unit, :fixture => false
g.stylesheets false
end
But alas, I'm not having any luck.
No detailled answer, but you should take inspiration there: https://github.com/ryanb/nifty-generators
Another similar question regarding the the error active_record [not found] pain in the nether regions =)
Over here: Rails: hook_for :orm not finding active_record
How to resolve:
Stay within the Rails::Generators namespace
This already solves most of the not-found issues.
configure your generator as a default. (anywhere within the Generators model space)
module Rails
module Generators
class Railtie < ::Rails::Engine
if config.respond_to?(:app_generators)
config.app_generators.orm = :my_own_model
else
config.generators.orm = :my_own_model
end
end
end
end
And you wont have any further hassles from rails g anymore.
nJoy!
Related
When I generate a model using:
$ rails g model example
Rails generates a factory for the model. Currently it adds the factory to test/factories however I need it to add the factory to spec/factories.
I'm using RSpec and everything else is generated to spec/….
Normally, the place where these files end up, is determined by a directive in the file config/application.rb:
class Application < Rails::Application
config.generators do |g|
...
g.fixture_replacement :factory_girl, dir: 'spec/factories'
...
end
...
In my Rails 3.2 app's application.rb I have the following lines to disable scaffold generators I don't want:
module MyApp
class Application < Rails::Application
# rest of the config...
config.generators do |g|
g.helper false
g.stylesheets false
g.javascripts false
end
end
end
The app is using the Draper gem and if I run rails generate then decorator is listed as one of the available generators. I assumed that adding g.decorator false to the above list would prevent rails generate scaffold SomeModel from generating the decorator files but they're still created. Can anyone tell me what I'm missing please?
Draper is configured to have decorators built by default for every controller. You can change the default configuration with one additional line in your application.rb file...
module MyApp
class Application < Rails::Application
# rest of the config...
config.generators do |g|
g.helper false
g.stylesheets false
g.javascripts false
g.decorator false
end
end
end
Here's the interesting bit from Draper...
https://github.com/drapergem/draper/blob/master/lib/generators/controller_override.rb
Called from the Railtie...
https://github.com/drapergem/draper/blob/master/lib/draper/railtie.rb
Note that you can still generate decorators explicitly...
$ rails generate decorator foo
Does anyone know of a rake task or RSpec call that will generate a bunch of empty files relative to the existing controllers, models, helper files and views that already exist within your application?
You can generate an empty scaffold set of rspec tests against an existing controller using something like this:
rails generate rspec:scaffold recipe
You can improve on this by passing the attributes of the model you want to generate against, like this:
rails generate rspec:scaffold recipe title: string slug: string description: text
You'll still need to do some manual editing, but this should get you most of the way there.
The best solution for this is to add hooks in place within environment.rb to create the spec.rb files within the rails application each time a model or controller is created.
Here's the code for that (using RSpec and FactoryGirl):
module RailsApp
class Application < Rails::Application
config.generators do |g|
g.test_framework :rspec, :fixture_replacement => :factory_girl, :views => true, :helper => false
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
g.stylesheets false
g.javascripts false
g.helper false
end
end
end
This should work:
Install the rspec-rails gem by adding it to your development and test groups in your gemfile gem 'rspec-rails'
Run the rspec generator from inside your app rails generate rspec:install
Read over this doc quickly to see how it integrates with your rails app RSpec-rails doc
My scaffold generator stopped working after we updated factory girl. Here's why happened. First, my config file tries to set up certain defaults for scaffold generation, like so:
class Application < Rails::Application
config.app_generators do |g|
g.template_engine 'mizugumo:haml'
g.scaffold_controller 'mizugumo:scaffold_controller'
g.assets 'mizugumo:js_assets'
g.test_framework :lrdspec, :fixture => true
g.fixture_replacement 'lrdspec:factory'
g.fallbacks['mizugumo:haml'] = :haml
g.fallbacks[:lrdspec] = :rspec
end
...
end
Where :lrdspec is the name of my company's scaffold spec generator. However, the most recent factory_girl_rails, in its initializer, rudely forces config.generators.test_framework to 'test_unit' unless your test framework is exactly ":rspec":
module FactoryGirl
class Railtie < Rails::Railtie
initializer "factory_girl.set_fixture_replacement" do
generators = config.respond_to?(:app_generators) ? config.app_generators : config.generators
if generators.options[:rails][:test_framework] == :rspec
generators.fixture_replacement :factory_girl, :dir => 'spec/factories'
else
generators.test_framework :test_unit, :fixture => false, :fixture_replacement => :factory_girl
end
end
What I am trying to figure out how to do, is to generate my own initializer that runs after FG's initializer, to set test_framework back to :lrdspec, as I want it.
I've tried dropping my own railtie into config/initializers, or adding a block to config.after_initialize in config/application.rb, and a number of other approaches, but haven't quite found the solution. (My knowledge of Rails' initialization sequence needs to be a bit deeper than it is' I think).
Thanks!
Okay - found a solution. Sometimes just posting a question can help in thinking it through.
The answer was to set my own initializer in the gem that holds my scaffold generator, and to pass :after => "factory_girl.set_fixture_replacement" to initialize() when I create that block. The fact that you can specify :after to the initializer isn't documented in the Rails docco, but can be deduced by discovering that Initializable uses TSort to sort its collection of initializers, researching how TSort works, and discovering that the stored :after/:before parameters are used in the methods that TSort calls back to.
So the fix was to drop this in the configuration Railtie for my own gem, the one that provides the scaffold generator:
initializer "lrd_dev_tools.set_generators", :after => 'factory_girl.set_fixture_replacement' do
generators = config.respond_to?(:app_generators) ? config.app_generators : config.generators
generators.test_framework :lrdspec, :fixture => true
generators.fixture_replacement 'lrdspec:factory'
end
Is there any command available for generating all missing spec files for existing models / controllers? I have a project that has several models that have been generated with out spec files.
In rspec-rails-2 which is intended for Rails 3 all of the rspec generators have been removed.
You can solve this problem by running the rails model generator. You can add -s to skip any existing files and --migration=false to skip creating the migration file.
Like so:
rails generate model example -s --migration=false
You could just run the generator and ignore the models/migrations/fixtures.
ruby script/generate rspec_model User --skip-migration --skip-fixture --skip
I've been looking into writing something to do this but there hasn't been any interest from others.
If the number of missing specs is rather small, you could simply run the rails generate commands for each components with missing specs.
When a conflict arises, simply opt not to overwrite the original file. The generator will ignore the existing files and generate the missing ones.
https://gist.github.com/omenking/7774140
require 'fileutils'
namespace :spec do
def progress name, x, y
print "\r #{name}: #{x}/#{y} %6.2f%%" % [x.to_f/y * 100]
end
def generate_files name
kind = name.to_s.singularize
collection = Dir.glob Rails.root.join('app',name.to_s,'**','*').to_s
root = Rails.root.join('app',name.to_s).to_s<<'/'
ext = case name
when :controllers then '_controller.rb'
when :models then '.rb'
end
count = collection.count
collection.each_with_index do |i,index|
`rails g #{kind} #{$1} -s` if i =~ /#{root}(.+)#{ext}/
progress name, index, count
end
end
task generate_missing: :environment do
generate_files :controllers
generate_files :models
end
end
# if you dont want certian things generated than
# configure your generators in your application.rb eg.
#
# config.generators do |g|
# g.orm :active_record
# g.template_engine :haml
# g.stylesheets false
# g.javascripts false
# g.test_framework :rspec,
# fixture: false,
# fixture_replacement: nil
# end
#