Why use gems for serving assets instead of the vendor file? - ruby-on-rails

I am relatively new to Rails and I have a question about serving assets from a gem vs just loading the files into the asset pipeline.
As far as I can tell, they do virtually the same thing in that they both make the files available in the asset pipeline to be called in the manifest.
What are the advantages to serving something like gem 'jquery-rails' as a gem instead of just putting /vendor/assets/javascripts/jQuery.js in the vendor assets and loading it that way?

The advantage is you don't have to add the file(s) to your repo and manage updates, you update the gem and you've updated the dependency. They can also add helpers to use the assets more easily.
Not all JS/CSS projects are out-of-the-box compatible with the asset pipeline too, so sometimes the gems will do that work for you as well.
Just because the files get served to clients doesn't make it much different than any other dependency in your application.

The gem includes the unobtrusive javascript for Rails as well as jQuery itself. It also allows you to user assert_select_jquery in tests.

jquery-rails is gem contains js file for both jquery.js, jquery_ujs.js. If you does not include jquery-rails, then you have include both jquery.js and jquery_ujs.js.If you are not using gem for jquery-rails, you have manually keep track what version jquery.js is used for jquery_ujs.js. Currently these dependency management is taken care by gem 'jquery-rails'.

Benefits:
You don't need to manually copy them when you get a new version of
jquery released, gem will make sure to add the latest codes only.
Check this link:
https://github.com/rails/jquery-rails/blob/master/lib/jquery/assert_select.rb#LC48
It provides couple of methods which helps while testing your code.

Related

How to Include Angular in a Rails App

To include Angular in rails, I can think of three basic methods:
Use gem 'angularjs-rails' (which no one seems to do).
Download Angular, add it to /vendor and manually include it.
Use Bower to require it and then manually include.
I suppose the advantage of Bower is just the dependency model but apart from that, why would I pick any one of these over any of the other options?
A good approach is to use Rails Assets.
From their website:
Rails Assets is the frictionless proxy between Bundler and Bower.
It automatically converts the packaged components into gems that are
easily droppable into your asset pipeline and stay up to date.

How to manage rails asset does not have gem

We always have ruby gem of famous javascript or css lib such as bootstrap-sass, ember-rails. But for some js lib such as bootstrap-lightbox, there are no gems sometimes. In order to manage these asset automatically, I found the jail(https://github.com/charly/jail) gem. But it seems that project is not so active now. Are there any better solution then just download and past file?
Many of those "assets gems" are just a basic skeleton with js/css assets, it should not be too hard to build your own and publish on rubygems!
An advantage of this, beside locking versions in Gemfile, is that you have control over them and don't risk screwing everything up during a bundle update.
I have found issues using external gems for managing assets, especially with bootstrap ones, sometimes the precompilation will break or they will upgrade the assets inside, breaking the entire site (or minuscole portions that you may hardly notice) with not-so-wanted changes.

Sharing CSS through Ruby Gem

We have common CSS styling in our organisation that most of the projects use. These assets (css, images etc) are included in every project's source code.
I would like to have a gem that could host these assets and the projects that use this gem would be able to directly use them. At the moment, I can only find ways to use generators and 'install' the assets into a project, not to use them from the gem itself.
The main requirement is that if there's a bug fix/ improvement made to the assets, just updating the gem should get me the latest in all projects that use the upgraded gem.
how do I go about doing this?
You can do this quite easily in rails 3.1+ if you make your gem a rails engine. Among other things if you add assets to an engine then you can require those CSS files from your application's manifest files etc.
There's a walk through on how to do this here and quite a few gems out there that wrap js/CSS packages with that exact aim of being able to upgrade the assets used without having to run generators or anything. For example the jquery-rails gem does this for jquery. A more complicated example is jquery-ui-rails, which bundles all the jquery ui js,CSS, images etc and lets you load only the jquery ui components you actually need.

Asset pipeline and gems

Imagine that I have a engine gem A that has your application.css and application.js
Those files are loaded via stylesheet_link_tag and javascript_include_tag. This works and everybody is happy.
Then comes gem B. That gem also has it's own css/js that it wants gem A to use. So it injects it into the header of gem A like so stylesheet_link_tag('gem_b'). Works fine in development but blows up when trying to deploy with AssetNotPrecompiled exception.
So what kind of solution do I have?
I can use config.assets.precompile on the main app. That's what I do now, but this really sucks.
Is there a way to inject into gem A application.css manifest somehow? That would be optimal.
Thanks.
Basically the idea is to always to only link application.js/css manifests. So you can't safely use stylesheet_link_tag('engine_a') but you can totally do stylesheet_link_tag('engine_a/application').

Create plugins or gems for Rails 3?

I have features I would like to be portable between my own Rails applications.
I wonder if I should create a gem or a plugin for each feature I want to be portable (sharable).
They are just for Rails (for now) because they include css, html, js and image files.
But I have been wondering, the things provided with plugins could be provided with gems too but not the opposite? So maybe it's better to learn how to create gems, because then you I don't have to learn how to create both gems and plugins? And gems seem to be more popular these days.
But then, from what I can understand one gem is shared between all rails app in the OS. So that means I can not customize it for each Rails app right? In that case, maybe creating a plugin is better cause it should be allowed to customize (editing css, js etc) each feature and to have it stored inside the Rails app itself and not in the OS level.
Some advices would be appreciated!
UPDATE:
So gem works great with css, html, js and image files? In a plugin I think you can have a MVC, your own models, views and controllers. Quoted from Rails guides "Storing models, views, controllers, helpers and even other plugins in your plugins". Is this possible too in a gem? Eg. I want to add a extension that gives me a nice Shopping cart (with own migrations, mvc, asset files) that will be hooked into the current Rails app. Is this possible as gem or only as plugin?
You're right that gems offer a little more than plugins. Versioning and dependencies on other gems being the main ones for me.
One gem needn't be shared across everything using ruby. You can install multiple versions of a single gem and specify in your environment.rb that a gem requires a specific version. E.g.
config.gem 'my-gem', :version => '1.2.3'
Also you can freeze gems into your rails application so that you know you are working with a specific version.
You might want to look at the jeweler gem which makes creating your own gems easier.
UPDATE
To include CSS, javascript etc I think you'll need to make an Rails engine which can then be bundled as a plugin or a gem. I've not done this but there's some coverage here and here.
The push with Rails 3 seems to be towards gems and away from plugins as a lot of support has been added to make gems work as well or better than plugins ever did. A well constructed gem is a great thing to have and share between different applications, and also reduces the amount of testing you will have to do since you can test the gem thoroughly before integration.
For extensions to Rails that use CSS, HTML and other assets, it might be that you need to build an engine to bundle this all up and allow it to fit neatly into an application.
As of Rails 4, plugins will no longer be supported.
Gems are the way forward.

Resources