I've been using Rails for a while and have always used gems in my gemfile, but I never really understood how the functionality of gems that I install actually become available. Say I use the has_permalinks gem (http://haspermalink.org/). It provides a .generate_permalink! method for my Model. Where does this method get defined? How come just I can use this method all of a sudden just by installing the gem? Is there some sort of include/require/load to initialize the gem's code so that it becomes accessible to the rest of the application? Also, where is this code stored when I install the gem?
I answered your questions separately, and out of order, but I think it actually might make it easier to understand the answers in this order.
Also, where is this code stored when I install the gem?
If you're using Bundler, you can do bundle show has_permalink and it will show you where that gem is installed. Here's an example of me doing it with the pg gem:
✗ bundle show pg
/Users/jasonswett/.rvm/gems/ruby-1.9.2-p320#jason/gems/pg-0.11.0
Where does this method get defined?
If you do the bundle show thing, it returns a path - the method is defined somewhere in there. (You can use grep -r 'def generate_permalink' /gem/path to find exactly where if you want.)
How come just I can use this method all of a sudden just by installing
the gem? Is there some sort of include/require/load to initialize the
gem's code so that it becomes accessible to the rest of the
application?
Look at this part of the doc about the Rails initialization process:
http://guides.rubyonrails.org/initialization.html#config-boot-rb
In a standard Rails application, there’s a Gemfile which declares all
dependencies of the application. config/boot.rb sets
ENV["BUNDLE_GEMFILE"] to the location of this file, then requires
Bundler and calls Bundler.setup which adds the dependencies of the
application (including all the Rails parts) to the load path, making
them available for the application to load.
It looks like, fairly early on in the process, Rails looks at your Gemfile and loads all your gems via Bundler. So there's your include.
Related
I've got some helper code (monkey patches) I tend to carry around from rails project to rails project via simply copying files or pasting code into the initializers folder.
I think a clean way to deploy different categories of my initalizer code would be to simply add gems to my project Gemfile that would do the equivalent of this for me. I'm not very skilled at creating gems or the deeper side of ruby on rails engineering so I just wanted to know if this were possible before I got started with it.
Yes, this is definitely possible. It should be probably enough to make a simple gem, put your monkey-patches there and require them in the gem entry point (e.g., if the gem is called foobar, then bundler will require lib/foobar.rb by default).
There is a guide on creating gems available in Bundler docs. In case you need to interact with Rails application configuration, you can take a look at Rails Engines.
I'm using ember-rails with ember-source and ember-data-source. But somehow the activemodel-adapter is not included in either of the gems. Or I'm missing something. I also searched bower, and can't find any. The code seems to be at: https://github.com/emberjs/data/tree/master/packages/activemodel-adapter
But it also needs compile. I'm wondering if there is an easier way to use it.
You must explicitly load a recent version of Ember Data. For example, add a version to the ember-data-source gem in your Gemfile:
gem 'ember-data-source', '~> 1.0.0.beta.7'
The active model adapter is included with Ember Data. Assuming everything in your project is global you could use it for your entire application like so:
App.ApplicationAdapter = DS.ActiveModelAdapter;
I am new to Ruby on Rails and I am trying to use some gems that require to apply some changes in the initial configuration.
In this particular gem it says I have to change the configuration parameters. Where do I find this in ruby 1.9 and rails 3
Thanks
You can put that code anywhere -- if it's setting up and configuring objects that will be used throughout your app and you want it run when the app starts, you can put it in an initializer. config/initializers/APNS.rb
As a Rails developer I feel a bit stupid asking this question but hopefully I will learn something new and someone can put me out of my misery! In my rails applications I use (other peoples) gems all the time, I also use plugins from the community or my own.
I understand the benefits of use gems over plugins as they are version-able, segmented, system wide, easier to manage and share etc etc but I don't really know how to go about making a gem for my rails apps!?
Do you always start with a plugin and convert it to a gem, I've seen the words 'package it as Gem'. Also the gem I'm thinking of building would be no good in a normal ruby program, it's only useful to rails apps. I'm not even sure if the semantics of that make sense, 'RubyGem' that will only work in a rails application!?
I would like to create a gem (if that's what I should use?) for a discrete piece of functionality for my rails apps. It will need to add a database migration, new routes and provide controllers and views or useful view helpers. I'm know I can achieve this via a plug-in but would just like to know how/why to do it as a 'Ruby Gem'?
To avoid the risk of Over-engineering, I usually start with the feature I need directly into the application. Then, as soon as I need to use the same feature into another project, I check whether it is worth to extract it into a plugin or even a separate application providing an API.
Plugins and Gems are often interchangeable. Gems provides several significant advantages in terms of reusability and maintainability.
On the other side, there are some specific known issue. For instance, a Rails app actually can't load rake tasks defined into a plugin packaged as a Gem.
Almost every Rails plugin can be packaged as a Gem.
For instance, take my tabs_on_rails plugin.
You can install it as a Gem specifying the dependency on environment.rb. Or you can use script/plugin install command as you would expect.
If you want to achieve the same result, make sure to follow the standard Gem layout and provide the init.rb initialization script required by Rails.
Also, you might want to create an install.rb and uninstall.rb file to include the post-install and post-uninstall hooks when the plugin is installed as a standard Rails plugin.
Last but not least, if you package a plugin as Gem you can reuse it in non-Rails projects and provide Rails-specific initializations using the init.rb file. Non-Rails applications will simply ignore it.
If you want to make a plugin for Rails, https://peepcode.com/products/rails-2-plugin-patterns gives you a good start. After that, make the plugin into a gem.
To make a gem, this resource http://railscasts.com/episodes/183-gemcutter-jeweler will be helpful.
As of 2013 you'll want to use Bundler and the following tutorials:
#245 New Gem with Bundler -
RailsCasts
Make your own gem - RubyGems
Guides
Take a look at Jeweler. Jeweler gives you a set of rake tasks to make gem versioning and building very easy.
I'm having trouble getting rubygems to work in my Rails app. Specifically, I'm trying to use the json gem, documented here: http://flori.github.com/json/ I can successfully use JSON.parse() in IRB and script/console but not in my rails app.
I know it's some combination of config.gem 'json' in environment.rb and other things, but can't find a good explanation anywhere.
Can someone give me a concise list of what is required to use this gem OR point me towards comprehensive documentation of using gems in Rails? thanks!
config.gem is used for gem dependency in rails and it does nothing more than telling rails that a gem is needed, and helping the user install the appropriate gem, etc (more details here: http://ryandaigle.com/articles/2008/4/1/what-s-new-in-edge-rails-gem-dependencies)
however by installing a gem, it should be able to be used by the rails app automatically, if not, probably you can add require "json" into environment.rb or in an .rb files in the initializers folder?
Hope it helps =)
I solved it. There's decent documentation here: http://apidock.com/rails/Rails/Configuration/gem
Once you have used config.gem in environment.rb, you should not need to 'require' it later.
My problem was that I had not stopped and restarted the server! It worked in script/console because everything was getting reloaded every time.