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
Related
I'm using the 'fastimage' gem and I'm not sure where to place the require 'fastimage' statement in my Rails application. What is the best practice for writing require statements? Where can I place it so that I can use the FastImage methods anywhere in my application?
You should include in in your Gemfile. After that, run bundle install. You do not need to type require since that is already handled for you. Do note that you need to restart the rails server in order for your app to include your gem.
I went trough the the shopifyApi documentation and it's explaining how to communicate with the API via post/put/get http verbs.
I am coding in Ruby and I was wondering where I could find a list of all the methods available (like product.add_metafield(params)).
I checked the gem server and didn't find any RDOC available for the api.
Thank you
Here is a neat trick. At your command-line try gem which shopify_api. That will list out the current version you are using for your current Ruby. Of course with RVM or RBEnv these vary wildly.
Copy and paste the result to your clipboard. An example from my CLI is:
/Users/fuzzy/.rvm/gems/ruby-1.9.3-p194/gems/shopify_api-3.0.1/lib/shopify_api.rb
You only need this part...
/Users/fuzzy/.rvm/gems/ruby-1.9.3-p194/gems/shopify_api-3.0.1/lib
With that in your clipboard, type subl or mate or vim or whatever your text editor is and paste in that path. You'll then have the gem at your disposal. If you navigate to the shopify_api/resources folder you'll see the product.rb file, showing off some methods you can use. You can see how most resources work this way. Learning Active Resource can also go a long way to showing off how the API gem provides functionality.
You can hack the gem once you get past this stage of exploration. You can re-open the modules and classes and add your own methods. Pretty neat stuff.
The command line interface based on Thor is also in there, and worth a good look. That is one of the coolest aspects of the gem in my opinion. see shopify_api/cli.rb
I'm in the process of upgrading a 3.0 Rails App to 3.1.4 including the Asset Pipeline.
I'm on Heroku, so I'm I have this in my application.rb
config.assets.initialize_on_precompile = false
I noticed that when I run:
bundle exec rake assets:precompile
it creates files in a public/assets directory (even though my assets are in app/assets already).
For example, it creates files like application-72b2779565ba79101724d7356ce7d2ee, as well as replicating the images I have in app/assets.
My questions are:
(1) should be uploading these files to my production server?
(2) if I'm suppose to be uploading these, am I suppose to update each application-xxxxxxxx or only the latest one?
To your first question: Heroku will not allow you to modify the filesystem. So your assertion is correct- You will need to pre-compile the asset pipeline before you send it up to Heroku, so that it can be utilized in your production environment.
And the latter: You'll want to make sure you have the latest compilation. Any others wont be used. The "xxxxxxx" portion is to make sure that your users have the latest and greatest version of your assets. It's a way of versioning what the browser gets, and making sure they're not caching a bad copy of the JavaScript, when you want to set up their cache to hold on to the JS and CSS files as long as they can, instead of constantly getting it from your web server.
Take my Heroku comments with a slight grain of salt, as I have not deployed to Heroku before. I just know how their system works to some degree.
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.
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.