Create plugins or gems for Rails 3? - ruby-on-rails

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.

Related

Ruby on Rails Gem or Bower for CSS and Javascript?

In Ruby on Rails, which is better for CSS and Javascript dependencies?
To install them as Gem or as Bower dependency? Such as jQuery and or Bootstrap?
It is better to install CSS frameworks like Bootstrap as a Gem. Here is my favorite Bootstrap installation guide: https://launchschool.com/blog/integrating-rails-and-bootstrap-part-1
jQuery is already included in the default Rails setup.
This is very much a personal preference. There are schools of thought that go both ways.
I haven't looked in a long time, but oftentimes the gems are usually behind the current release of front-end libraries.
UI portability is greater if you keep the frontend/backend logic completely separate. If you wanted to switch to another backend tomorrow, how long would it take?
Using gems is faster, and you have a single tool (bundler) to handle the depedencies.
I have avoided providing my personal preference in favor of a neutral post.
AS my opinion ....
rather than gem/bower, you should download files and integrate to project
like for bootstrap download bootstrap files

Rails 4 - Adding JS assets via gem

I am using a gem that somebody else wrote to serve the fabric javascript library. The gem is using an old version of the library (1.3) and I'd like to be using 1.4 (the latest version). I haven't found any other gems using this version. My question is, is this the best way to load assets, or is there a more preferred method? And, if so, how would I go about building this gem with the latest version of this library?
In my opinion, it is good to do so in most cases.
In your situation, depending on how much time you have, you may want to do one of the following:
1. Contribute to the gem
If the gem is open source, you may fork it, update to the newest version, and do a pull request.
By this way you also give contribution to the rails whole and the others who are facing the same problem as well.
Downside is this takes time. You have to wait for the author to accept the pull request and wait for the next version of the gem. But you can point your Gemfile to use your forked version until the new version is out ;)
2. Write your own gem
Writing a gem for rails providing assets is actually not difficult. You may follow other existing gem's structure and should be easy to understand.
A good example is https://github.com/rails/jquery-rails
Downside is you have to maintain the gem. Otherwise when fabric 1.5 is out, another one would ask the same question as yours again.
3. Put the assets in your vendor directory
Rails project by default do have a vendor directory. It's ok to put external assets here as well.
The above are my preferred way to manage external assets.

Best practices when including Rails models in another application

I'm developing a ruby application that uses the models and data from another Ruby on Rails web application as its main data source.
The Rails models were included in this application by including the environment.rb file in the main file like this:
# Require Rails
require_relative "../../RailsApp/config/environment.rb"
This works but there are uninitialized dependencies when loading models that use gems that are defined in the Rails Gemfile. (For example, acts_as_taggable_on, rack-pjax, devise, etc)
This ruby application dependencies are also managed through Bundler, so at the moment the only way to get the application working is to copy and paste the contents from the Rails' Gemfile into the ruby app's Gemfile.
Obviously this approach is not optimal as the gem requirements are duplicated.
Is there a better way to include Rails and the dependencies that its models require in another application? Is there a way to include a Gemfile into another?
Here are some options, in order of simplicity
Just keep everything in one app, a lot of stuff is easier this way
Use plugins to share common code
Use web services to share data
You could extract the models and code out from RailsAppA into a Gem. RailsAppA then includes that Gem and uses it.
The gem can remain in a private repository and does not need published.
Both apps would then do something like:
gem "yourapp-modelage", git: "http://github.com/you/yourapp-modelage.git"
Then, App2 would also use that Gem... How much goes into the Gem will depends on how much you need to re-use.

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.

What's the best way to require source files when writing a gem

I'm converting the models folder of a rails app into a gem so more rails app can use the same domain model layer.
In the initial rails app, the loading of all model files is handled by activesupport so there no require statement everywhere. But in the gem version, it has to be done manually. I had a look at the code of popular gems such as rspec, factory_girl and state_machine and it looks like they all require all necessary source files in one file, usually named after the project.
The downside of this approach is that you need to maintain one file listing all the others and that seems a bit clumsy. And even though I have hit that problem yet, I can foresee cirular dependency issues.
Another way would be to have each source file requiring the files it needs. That would work in the standalone gem as well as in the rails app. But I haven't seen examples of gems using that technique so I'm wondering if there is a downside I'm not seeing?
thanks
You're talking about model files, if so, simply adopt the same structure as a standard Rails app and make your gem inherit from Engine. Everything will be included painlessly.

Resources