How to make a complex gem in rails 4? - ruby-on-rails

I want to make a complex gem for Rails 4, but I don't know how. I only find tutorials for simple gems which for example offer only a simple function.
Is there a tutorial or any other help for the development of a gem which also have models, views and controllers?
Thanks for help!
kagutsuchi

You may be looking for an Engine, provided that you're trying to add functionality to a Rails app.
Isolated engines function like Rails apps, and can be mounted in config/routes.rb so that they are accessible.
Traditional engines, examples of which include Clearance and Devise, provide functionality which interacts directly with the host app. These should only be considered in special cases, such as when you will need to share models.

Related

Adding HTML to a Ruby on Rails Gem

I'm not a RoR expert, trying to write my first gem which includes javascript, erb, etc. Is this possible, it seems like every tutorial and example code I can find only includes ruby code. If it is possible, what does the directory structure of the gem look like with javascript and erb files? Thanks.
What you want is an engine.
Engines can be considered miniature applications that provide
functionality to their host applications. A Rails application is
actually just a "supercharged" engine, with the Rails::Application
class inheriting a lot of its behavior from Rails::Engine.
Therefore, engines and applications can be thought of almost the same
thing, just with subtle differences, as you'll see throughout this
guide. Engines and applications also share a common structure.

Creating Rails Gems

I want to build my application in a modular way: For example I might have:
Users->has_and_belongs_to_many->Projects
Users->has_and_belongs_to_many->Tasks
Projects->has_many->Tasks
Tasks->belongs_to->Project (1 task belongs to 1 project.)
Note: Projects AND tasks can have many users.
The way I was thinking of building this is by doing:
User = Gem
Projects = Gem
Tasks = Gem
Each can return either json (for ember) or html. Neither depend on each other, The idea is that each is just a detail. Rails, ember and html are all just details.
How could I go about this and at the end of the day hook them together like a puzzle? or is this even feasible?
Right now I have the user piece of this concept almost done. It contains models, tests, controllers and views. Can I bundle that as a gem or should I only bundle the controller and the models? This "User" gem would make use of friendlyId gem to make the urls look nice, infact all the "gems" (project, tasks and users) will depend on this gem.
What would you recommend to do to have the kind of modularity I want? is it good practice? bad practice?
Pivotal Labs made a presentation (Euruko 2013 in Athens) and they showed a rails engines approach similar to what you are describing. Here is the presentation http://www.ustream.tv/recorded/35107339/highlight/377037
I haven't seen it in practice though, but I would like to.
I believe use of Rails engines is the way to go.
Each Engine can be an app in itself.
For instance Devise - gem that adds a lot of authentication functionality into your app is a Rails Engine. It provides its own controllers, helpers, mailers and views that you can use from your app.
I personally was working in projects that were using Engines to plugin i18n web backends (admin page that allows entering and saving translations to Redis) into many apps and to plugin users' bug reports and Question&Answer functionality into several existing projects.
Each engine is being included in a project as a gem, it can consist of anything that normal app does - controllers, views, models, assets, other gems...
I personally haven't heard of any success stories with such approach (but I don't know if anyone tried though), so if you have a solid concept in mind maybe it will work for you.

Using an engine, or a library gem

I wanted to separate out common models (and their migration) out to a gem. I was wondering if I should an engine, or make a library gem for this purpose.
Thanks!
Engines are great for providing a full MVC stack. If you plan on adding more than common models it is a very clever move since it will add a lot of flexibility to your application.
Otherwise you may find the workflow over head to much compare to the functionality provided.

Could someone please define an Engine in Ruby in Rails?

In computing terms, an engine is something that is continually producing output based on input. But in Ruby, the term seems a little bit loose. The people who've created Refinery CMS have taken to calling gems that extend the functionality of their system, 'engines'.
Basically, what I want to know is, is Spree, the open source ecommerce cms written in ruby, an engine? Would calling it the 'spree engine' be correct?
As defined by Rails, an Engine is a lot like an application within an application. Spree is one of these, and there are others. Each engine has its own app folder with the same sort of structure you'd see in a top-level application.
You can combine one or more engines together into an application, then add your own functionality on top. That's what makes systems like Spree far more flexible than a fixed-puropose Rails app that you have limited control over.
Things that extend Rails are only truly engines if they are self-contained applications. Many gems add functionality that's much more specific than that, so are better termed "plug-ins" or "modules" depending on the phrasing.
It's actually pretty easy to build your own engine and can be useful for separating and re-using code across several different applications.
I think that there is quite good explanation in guide Getting Started with Engines.
Spree is actually comprised of many engines...
The overcooked version: Engines come kitted with (many of) the guts of a typical rails application, with a few bonuses: namespacing out of the box, generators for easily copying migrations, and the ability to mount it in another rails application.
From http://guides.rubyonrails.org/engines.html
1 What are engines?
Engines can be considered miniature applications that provide functionality to their host applications. A Rails application is actually just a "supercharged" engine, with the Rails::Application class inheriting a lot of its behavior from Rails::Engine.
Try to read this guide: http://guides.rubyonrails.org/engines.html and also this cast: http://railscasts.com/episodes/277-mountable-engines

Models shared among applications : DataMapper Rails Other

I have a set of models I need to share among several rails3/sinatra/etc applications. I haven't seen anything like this yet and I'm curious what is the most effective way to go about this in a DRY manner? Can I specify a central area for models, can I create a gem that only brings in the models I need? How have other people approached this issue. I was thinking of making a smallish gem or something I don't yet know about to handle this.
I'm using Datamapper, but this is also a more general issue of structuring multiple rails/non rails ruby apps.
You might find it's easier to have a submodule in your repository that contains your models and associated unit tests than to create a full-fledged gem. This way you can patch from one app to the other instead of having to drive everything top down.
You can create public API to models you want to use in other apps.
In rails you should already have REST controllers, so you can use ActiveResource in the other apps.
You can pack your ActiveResource classes in a gem just to simplify thing and to keep things DRY.
You can check: http://api.rubyonrails.org/classes/ActiveResource/Base.html for some examples.
And it doesn't matter if you're using ActiveRecord or DataMapper.

Resources