How should I package up reusable extensions across multiple projects - ruby-on-rails

We have some business specific extensions to common gems such as Sunspot. These extensions need to be run on startup since the files they belong are already defined.. ie rails will not try to autoload these because their constants have been defined. To solve this loading problem we have but these files in config/initializers/extensions.
First off, is this ideal?
Secondly (and more importantly), how can/should we package up these extensions/overrides so we can reuse them in other projects that we have? As of right now we are cut & copying the files across the projects... yuck.
Thanks for you help

I'd put the extensions in a gem. Then provide a small api call you can put in an initializer to load the gem's functionality if necessary. I don't know that you'll be able to get away from the use of an initializer, but by putting the meat of the functionality in a gem you'll at least have an easy way to share it across projects.

Related

Use Tailwindcss classes in Ruby Gems

I am working on externalizing some of an app's functionality, so that we can use it across multiple apps. The functionality in question contains several ViewComponent's that use TailwindCSS for CSS. These CSS classes work as expected when the files are contained internal to the app, but fail to be loaded when the files are externally contained in the gem. Likely due to them now being external to the TailwindCSS config's content.
The methods I have tried are:
Including CSS through an Engine in the gem as mentioned in this blog
Safelisting classes which works, but requires that the end user add all required classes into the main app. I am hoping for a more dynamic approach to avoid hard coding classes.
Following the Third-Party library instructions to attempt to hack together a Gem way of dynamically adding the files to content. (Can be linked to via Github if that is an option)
Most promising to me seems to be the third-party options, which unfortunately caters to NPM packages, while I am trying to do the same with a Ruby gem. Any pointers on including via a link for dynamically loading the classes would be appreciated!

Integrating multiple apps in Rails

I am working on a project in Rails. It contains multiple sub-projects. They have a common login and the rest is separate for all. I want to integrate them all in the main project. The sub-projects are pretty big, so putting them all together will make it cumbersome to manage the code. Is there any way to integrate the sub-apps or gems in the main project?
You might consider breaking your apps into engines. It's a great way to isolate functionality and make code modular. Here's a link to the Rails engine docs: http://guides.rubyonrails.org/engines.html
If you need examples of real-world uses of engines you might consider looking at the code for Spree: https://github.com/spree/spree
With Spree you can add custom functionality by installing or building extensions, which are effectively Rails engines.
If you want to reference local gems/engines, you can point to them in your Gemfile like this:
gem 'mygem', :path => '/path/to/gem'
But make sure that the individual gems within your project don't have a .git folder, or you might run into errors regarding sub-modules.

Organizing shared layout and assets between several projects

Every time I create a new Rails application, and for the admin part, I copy the layout and assets from another project to the new project.
I think it's obvious how many problems this approach causes. I am thinking about organizing my layout, and assets in a proper way.
What I have in mind is creating a gem and putting everything in that gem. But before I try that, I wonder if there is a better way for organizing these files?
Gem is good if you want to share codes among apps.
If, like your case, the shared parts have routes/views, an engine would be better suited, which is also a kind of gem. You can check the guide for details: http://guides.rubyonrails.org/engines.html

Why is there Rails.rb files all over the place?

Was digging around my Rails applications and noticed that there are rails.rb files all over the place. In my ruby gems directories like:
...gems\devise-2.0.4\lib\devise\rails.rb
...gems\cucumber-rails-1.3.0\lib\cucumber\rails.rb
...gems\railties-3.2.3\lib\rails.rb
I am assuming that there are executed whenever you issue some command like "rails xxx". So all these extra rails.rb files combine with the original rails.rb file to essentially make one big rails.rb file. Essentially, when we type in "rails xxx" it goes thru all them all?
Just looking for some confirmation PLUS a little more knowledge about this. Thanks.
The best way to understand what these rails.rb files are doing, is to read the source code.
ralties
devise
cucumber-rails
As you can see, in any library the file assumes a different scope. The common behaviour is that the file rails.rb normally contains the code required to initialize the library when loaded from a Rails project.
BTW, this has nothing to do with the script/rails command and there is no "big rails.rb" file.
The files are not generated but are simply source files of these libraries you are using.
In this case they are probably rails-related classes that either extend Rails in some way or modify it or make the library interact with Rails.
Rails is a very common framework in Ruby land so most if not all libraries will have some sort of integration with Rails.
By no means are all of those loaded when you run rails XXX but rather when your application loads these libraries their rails.rb files may be executed to provide some sort of integration with Rails.

What are the performance implications of using require_dependency in Rails 3 applications?

I feel like I understand the difference between require and require_dependency (from How are require, require_dependency and constants reloading related in Rails?).
However, I'm wondering what should happen if I use some of the various methods out there (see http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/ and Best way to load module/class from lib folder in Rails 3?) to get all files loading so we:
don't need to use require_dependency all over the place in the application and
don't have to restart development servers when files in the lib directory change.
It seems like development performance would be slightly impacted, which is not that big of a deal to me. How would performance be impacted in a production environment? Do all of the files generally get loaded only once if you are in production anyway? Is there a better way that I'm not seeing?
If you could include some resources where I could read more about this, they would be greatly appreciated. Some blog posts said that this behavior changed recently with Rails 3 for autoreloading lib/* files and that it was contentious, but I didn't see any links to these discussions. It would be helpful for considering the pros/cons. Thanks!
The code reloader is disabled by default in production. So if you are calling require_dependency at the top of a file it is going to be executed only once.
The Rails 3 change you mentioned is really small. You can usually call Foo and it will be loaded from app/models/foo.rb automatically. Before it could also be loaded from lib/foo.rb. (These directories app/models and lib are called autoload paths.) Rails team decided to remove lib from autoload paths in the 3rd version. You can still put it back. But it is encouraged to leave in lib less frequenttly-changed and project-specific files. If you have something that does not belong to any of the default app subdirectories like app/models or app/controllers you don't have to put it in lib. You can add your own subdirectory. I have app/presenters, for example. There is a discussion on the old issue tracker if you want more info on that.

Resources