I've written a custom Rails 3 generator that generates rspec tests for each one of the models in my app. I've also written one for generate rspec tests for routes. When I run
rails generate
I get the following output (this is a segment):
ModelSpec:
model_spec
RouteSpecs:
route_specs
Does anyone know of a way that I could get it to group those like so:
SpecGenerators:
model_spec
route_specs
The directory structure is:
generators/
generators/model_spec
generators/route_specs
Judging from examples of rollbar, kaminari:config and kaminari:views, I assume this is automagically derived from your module structure.
So I guess that if you structure your code like follows, you'll achieve what you want.
#in generators/spec_generators/model_spec_generator.rb
module SpecGenerators
module Generators
class ModelSpecGenerator < Rails::Generators::NamedBase
#in generators/spec_generators/route_specs_generator.rb
module SpecGenerators
module Generators
class RouteSpecsGenerator < Rails::Generators::NamedBase
Related
I am in process of writing a Rails Engine, and as part of it I have a generator script that copies some migration files.
The generator is located here
lib/generators/install/install_generator.rb
The generator looks like this
module Calligraph
class InstallGenerator < Rails::Generators::NamedBase
...
...
end
end
In the host application, if I do a rails g, I see this along with other generators.
Calligraph:
calligraph:install
If I hit
rails g calligraph:install
it comes back with
Could not find generator calligraph:install.
Any idea on what's missing/wrong?
Try moving your generator to
lib/generators/calligraph/install/install_generator.rb.
Because your generator is defined within a module, Rails expects it to be contained within a subdirectory with the same name, just like namespaced controllers or other Rails extensions that live within modules.
Alternatively, you sometimes get a "could not find generator" error if you have a syntax problem in your generator, but the console would also spit out a trace and details on what that error would be if that were the case.
For your generator to work correctly, you also need to require rails/generators somewhere in your engine. I usually do it at the top of the generator file, but since rails g is picking up your generator it seems like you have taken care of it somewhere.
We're in the process of making a major database change to our Rails application. In order to be able to interop with the existing code, my plan is to do all the work in module namespaces to keep them separate from the existing models. However, I'm running into Rails autoload problems.
My file structure is like:
app/
models/
entity/
new_thing.rb
old_thing.rb
Where new_think.rb contains something like
module Entity
class NewThing
end
end
and old_thing.rb contains something like
class OldThing
end
OldThing gets autoloaded fine, but I keep getting errors like this:
Expected app/models/entity/new_thing.rb to define NewThing
Is there a way I can get it to correctly expect entity/new_thing.rb to define Entity::NewThing?
Try:
In your old_thing.rb
class OldThing
Extend Entity
end
or
class OldThing
require "entity/new_thing"
end
I'm new to Ruby (RoR) and rspec.
I have the basic project scaffold and a controller within project/app/controllers/books_controller.rb
Then I'm trying to setup rspec in project/spec/controllers/book_spec.rb
There also exists project/spec/spec_helper.rb that book_spec.rb requires. This file is where I'm trying to include the books_controller.rb file.
How do I include the books_controller.rb file so book_spec.rb has the Book object so when I run rspec, it works?
Currently I've tried things like require_relative "../app/controllers/books_controller" and it doesn't work. It gives me an error like:
uninitialized constant ApplicationController ... in 'require_relative'
Any help would be great.
You don't need to manually include your controllers, just follow the rspec naming conventions and describe the desired object and everything will work fine.
Your controller spec should be named books_controller_spec.rb. That is the exact same name as your controller with a _spec added at the end. This is not a hard requirement but a highly suggested convention as a book_spec.rb really implies a Book model spec rather than a controller.
The critical part is that in your spec you describe the desired object, e.g.
describe BooksController do
#...
end
You might also want to have a look at the rspec-rails gem which provides some useful generators for specs. Ideally you integrate with Rails so whenever you generate a new model or controller a new spec is created for you as well.
When using the rails generators with an Rails::Engine, it does not seem to pick up any template files that are put into the lib dir. As instructed here
http://guides.rubyonrails.org/generators.html#customizing-your-workflow-by-changing-generators-templates
Right now I have
lib/templates/rails/scaffold_controller
I have also tried
lib/my_engine/templates/rails/scaffold_controller
Has anyone else tried this.
It seems that this is not supported for Engines
In a Rails app the Finisher takes care of adding this to the path
module Rails
class Application
module Finisher
include Initializable
initializer :add_generator_templates do
config.generators.templates.unshift(*paths["lib/templates"].existent)
end
......
So this must be done in the Engine config in order for this to work.
module MyEngine
class Engine < ::Rails::Engine
config.generators.templates.unshift File.expand_path("lib/templates", root)
end
end
Is this a bug or the desired behaviour?
Above answer (by stellard himself) doesn't fix my case in Rails 3.2, but How to override a rails generator template in a gem? fix it. Just pointing out for the person like me.
If you use rails g generator MyGenerator in the root path of an Rails 3.2 engine you'll get something like this:
class MyGenerator < Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)
end
which doesnt pollute your Engine class and is much more localized to the generator.
I have a tirable orgnizing my Models in a Sinatra project.
Let's say I have 2 models: Post and Comment, nn Post model, I have to call Comment model. And now I have <class:Post>': uninitialized constant Comment (NameError).
I know its an issue in ordering the requiring for the models, but what about if I have lots of models? What's the Rails way in requiring models, etc.?
UPDATE
I use this code to auto_load my models in Sinatra/Rack/Grape applications. This code should be at the top of your code ie in the boot file.
models = File.join(File.dirname(__FILE__), 'app', 'models') # path to your models
$LOAD_PATH << File.expand_path(models)
# Constent Missing for requiring models files
def Object.const_missing(const)
require const.to_s.underscore
klass = const_get(const)
return klass if klass
end
You should put all of your models in a folder, such as lib in your application, then you can add this to the top of your Sinatra app file:
$: << File.dirname(__FILE__) + "/lib" # Assuming app.rb is at the same level as lib
require 'post'
require 'comment'
You should organise your code so that you do not call other models until all model declarations are loaded.
The Rails way is based on a very nice Ruby feature: const_missing. You could write your const_missing method or looking around the web for a solution with const_missing and sinatra.
no prob when I tried this
a Comment if it is in a method of Post shouldn't be actually evaluated
there must be some circumstance triggering the NameError
don't call Post in the body of the class declaration
load all the model files per the first commenter's suggestion
shouldnt be having the same reference troubles as Java per se
in a dynamic lang like Ruby