I am writing a gem that requires rails as a dependency (for using Rails methods like underscore, camelize and others).
Is 'gem' still a gem or is it now something else (Rails Plugin?) since I have rails as a dependency?
You don't have to depend on Rails as a whole (in fact if it really is a standalone gem, I would recommend that you do not) you can depend on just the parts of it that provide the functionality you need, in this case you are talking about ActiveSupport.
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 building an engine, and I want to use VCR and Webmock for testing.
The documentation within the Gemfile generated when an engine is created, seems to suggest that all an engine's gems should be loaded via gemspec, but the only options for this are add_dependency and add_development_dependency. If I use the latter, VCR and Webmock get loaded into my development environment, and I then have to explicitly disable Webmock in the development environment. I'd rather not do that as a host app may want these gems to work in development, and my engine disabling them may be unexpected.
The obvious solution would appear to be to use the engine's Gemfile:
group :test do
gem 'vcr'
gem 'webmock'
end
Is this the right way to load gems that are only used when testing an engine?
Are there any gotchas doing this?
One of the well known rails engines, rails_admin (https://github.com/sferik/rails_admin) uses that approach, so I believe it can be considered a good practice.
What's the load order for Rails app and Rails app's Rails Engines?
My guess is that the Rails app Gemfile is the determining factor for a gem being loaded or not loaded. This might be worth a try in a Rails test app.
I believe the answer is that there is nothing wrong with declaring in an engine's Gemfile, gems only used for testing and debugging the engine code. Further, I think the Gemfile template should be made less ambiguous, and have submitted a pull request to this effect:
https://github.com/rails/rails/pull/11881
What is the difference between the two and when one should be used instead of the other?
An Engine in rails terminology is a actually a subapplication of a web-application. For instance, something like a blog, a forum, or simple authentication: these are not full-blown applications, but pages/views/controllers/models that can be added to any rails application.
In rails2 this would be done using a plugin. Now since rails3 an engine can be packaged in a gem.
A gem is a ruby library, which can be found on http://rubygems.org and it is the standard (only) way to package and distribute ruby code to other rubyists.
So to conclude:
A gem: is a generic library, which can be easily installed, which are version-managed, have dependencies and such.
An engine: is a sub-application of a Rails application, and since Rails 3 these are distributed as a gem (which is awesome!).
So when will you use one or the other:
create a gem if you want to share ruby-functionality
create an engine (and package it in a gem) if you have parts of your rails application that can be used more generally.
Hope this helps.
I just discovered the ruby-on-rails-gems tag (as opposed to the tags rubygems, gem, bundler, and ruby-on-rails-plugins).
Is there such a thing as a "Ruby on Rails gem", as opposed to an ordinary Ruby gem, apart from gems that merely have Rails or one of its components listed as a dependency?
It is a bad tag, it seems like it is mostly used by newbies, and it is usually paired with rubygems (which makes sense). Going through and removing the tags, only 64 questions, so it shouldn't take that long.
EDIT
Done. Not sure how SO works with this, but it doesn't seem to come in up autocomplete anymore. Some questions were literally tagged ruby-on-rails ruby-on-rails-3 ruby ruby-on-rails-gems ruby-on-rails-plugins. We need to evangelize the DRY principal when tagging SO posts :)
No, not that i am aware of. There is a rails gem which is basically Rails, aka Ruby on Rails.
Gems are packages of Ruby code. Rails itself is a gem, and so is ActiveRecord, ActiveResource, etc etc.
I presume the tag is referring to gems that are compatible with Rails, such as Devise or acts_as_paranoid.
I guess it could be interpreted as "gems that are specifically made to work with Rails". There's plenty of gems which wouldn't work outside of a Rails app. I don't think it's a very useful tag though.
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.