I am creating a gem for a Rails project and I got some troubles to
understand how generators and initializers work.
I would like to
initialize my module loading some stuff from the database from models
related to tables my gem should create with a migration file.
Problem is : if I create a Railtie and put it my gem lib directory,
when I try to run my generator (to create the migration template file
for example), it's already trying to run the Railtie even though
tables required don't exist yet (because the migration file has not been executed yet).
How to restrict the "scope" of the Railtie ? I would like it only to
run when booting Rails from a server (webrick, thin, ...) or from the
console, but not for any rake tasks (including generators). I think
that rake tasks (like generators) load the entire Rails environment
and my problem should come from that.
Is there a simpler way to do what I want ?
any help or advice appreciated.
Related
I have a Rails app with a spec folder full of rspec tests. Many of them reference resources in my app, such as the 'User' resource. Everything is fine on my machine, but when I try to setup the app on a new machine and build the database with rake db:setup, it starts the whole Rails app, and for some reason, parts of the rspec tests get evaluated. Since one of them is referencing the 'User' resource, for which a database table has not been created yet, the rake task fails with relation "users" does not exist.
I can easily solve this my moving the spec folder out of the parent directory, running the setup, and then moving it back, but this is annoying. Obviously, I'd like for the spec files to be ignored during rake tasks like this. Any ideas?
This SO Answer helped me: FactoryGirl screws up rake db:migrate process.
This is the specific solution that worked for me.
In your gemfile, change factory_girls_rails so it isn't required
gem 'factory_girl_rails', :require => false
Then require it in your spec helper
require 'factory_girl_rails'
While creating a Rails application:
user$ rails new App
All the other files get created, i.e. app, config, db, doc, script, test, Gemfile, etc I find that the Gemfile.lock fails to be created. Any particular reason why this could be happening? I am facing errors in bundling gems, though I do not know whether the absence of the Gemfile.lock file is causing this. Please help!
you dont get a lock until after you do your bundle, and whenever there is a well form group of gems built (with all dependancies available..)
if you run:
bundle install
I think one should get created for you.
or
bundle update
if you have a lock file and have an updated gemset
Currently it seems Heroku is determined to pre-compile assets when I push my code up to my instances.
This is great for production servers, however for my "RAILS_ENV=development" server, this causes issues, as I now get pages with all the JavaScript files served up individually from my asset manifest, and then another file with the same code all grouped up as the pre-compiled asset.
This cause my jquery datatables libraries to break, throwing popup errors, which I don't get on my local environment (development or production) or in my production Heroku instance.
Is there anyway to disable pre-compilation of assets on Heroku for development mode instances ? Or is there any reason why these aren't already disabled on development Heroku servers already ?
If Heroku detect a public/assets/manifest.yml file then they will not attempt to precompile your assets and assume you are dealing with them yourself. More details at http://devcenter.heroku.com/articles/rails31_heroku_cedar
AFAIK, Heroku has to precompile assets to work around their readonly FS and the fact that the Rails asset pipeline wants to write files to the FS. The only thing I could suggest would be to work out why your assets are breaking when being compiled.
I worked around this by adding some voodoo to my Rakefile to disable the assets:precompile rake task.
first I add the user-env-compile labs component
heroku labs:enable user-env-compile
then add this to the beginning of my Rakefile
# found from http://blog.jayfields.com/2008/02/rake-task-overwriting.html
# used by conditional heroku asset compile magick
class Rake::Task
def overwrite(&block)
#actions.clear
enhance(&block)
end
end
Then I add this rake task in lib/tasks/disable_assets_on_heroku.rake
if ENV['RAILS_ENV'] == 'development'
namespace :assets do
task(:precompile).overwrite do
puts "Asset precompile skipped in #{ENV['RAILS_ENV']}"
end
end
end
I've fixed all the errors about "xxx" is not compiled and all the assets show up -- when running locally everything works fine:
All ajax requests work
Form submissions use the rails remote tag and fire off properly
However when running in production mode locally (and on Heroku):
Some ajax will work -- however things like PUT's that should be updatating records (and do in dev) don't... They will hit the page but not do the actual database update
Remote forms are completely broken and resulting in regular form submission
The source can be cloned from here: https://github.com/bluescripts/reru_scrum
Maybe I'm miscompiling the assets wrong or maybe I'm missing an appropriate include in my application.js file?
I've been compiling via:
rake assets:precompile
You're missing //= require jquery_ujs in your application.js. This file comes with jquery-rails gem and is responsible besides other things for handling remote links and forms.
Btw, I'd suggest removing .Gemfile.swp from your repo and adding .*.swp to .gitignore.
A lot has been written about engine development, and using a dummy app for testing.
In our case we're developing an engine that is not a stand-alone entity, but has dependencies on a real Rails 3 application. We still want this code to live in an engine, and not become part of the app, because the engine's job is to import data from a legacy system that has its own tables and model mappings, and we want to eventually remove it again.
The data mappings between the old legacy tables and the new schema are complex, and we want to TDD (using rspec) the engine.
I've followed Jose Valim's book "Crafting Rails Appliations" and am using the enginex gem.
I've replaced /spec/dummy_app with a git submodule pointing to a real Rails 3 app.
I'm having trouble loading the models from the engine (undefined symbol errors), as the real app's Gemfile doesn't point to the engine, and I also can't modify config/application.rb, to require the engine (which is what the dummy app does, as explained on pages 15-16 of the book).
I'm including the engine's lib folder into the load path $: in spec_helper and the paths are available.
Putting the require into spec_helper.rb didn't solve the problem.
I'm wondering if there is an internal Rails API (or a clever monkey patch) to hook into the boot sequence of the real app and require the engine, without having to modify the real app's code (as it's in a submodule).
Another issue I'm not fully sure about is that I have 2 Gemfiles (one in the engine and one in the app), and when the engine is active, they should both be used.
Thoughts?
So, I figured out a few things and will answer my own question, now that I got it to work.
For simplicity, I'm going to refer to the name of my gem as "my_gem" and "MyGem":
In the engine.rb file, I added:
require 'my_gem'
require 'rails'
This fixed errors of the type:
my_gem/lib/my_gem/engine.rb:2: uninitialized constant MyGem::Rails (NameError)
In spec_helper.rb, I added right up top:
require 'bundler/setup'
require 'my_gem'
This is to make sure Bundler is initialized right away, and not through the app. That way I can load MyGem here, and it'll be hooked into the initialization sequence of the app. This fixes NameError exceptions for the engine's model classes.
That leaves the question of what Gemfile to use. The trouble is that my app has its own gemfile and the gem/engine needs its separate dependencies in its own Gemfile.
I couldn't find any API for Bundler to pass two Gemfile to it, in fact Bundler seems to be built around the assumption of a single authoritative Gemfile. So I generate one in spec_helper. I take the app's gemfile and append gemspec which points to the gem's dependency in GemSpec format. (The hint about gemspec is missing from Jose Valim's book by the way).
I don't know if there's a better way than concatenating files during test startup. If you know of one, please respond.
Helpful resources were:
Clarifying the Roles of the .gemspec and Gemfile by Yehuda Katz
Bundler Documentation for gemspec