Rails Engine - Gems dependencies, how to load them into the application? - ruby-on-rails-3

I'm doing an engine here, it works alright in stand alone.
When I transform it into a gem, and load it inside another application, I get a lot of undefined errors, coming from my engine gem's dependecies.
Here is the gemspec:
s.add_dependency('paperclip')
s.add_dependency('jquery-rails')
s.add_dependency('rails3-jquery-autocomplete')
s.add_dependency('remotipart')
s.add_dependency('cancan')
In the application, when I do a bundle install, it lists all these dependencies, but as i run the application I receive a lot of undefined methods errors (has_attachment from paperclip for example). It seems that the application doesn't load the engines dependencies.
Is this the default behavior? Can I change it?
Same thing happened with a plugin inside the engine.
If I insert by hand those gems, in the application Gemfile, all works...

Include them in your gemfile and run bundle install. Then require them in your lib/<your_engine>/engine.rb file. Don't forget to require rubygems
require 'rubygems'
require 'paperclip'
require 'jquery-rails'
require 'rails3-jquery-autocomplete'
require 'remotipart'
require 'cancan'
Then in your host app (The app where you included your gem) run bundle install/ bundle update (bundle update did the trick for me) and then everything should work perfectly. You can also test this by starting the console in your host app and just type the module name e.g.
Loading development environment (Rails 3.0.3)
irb(main):001:0> Paperclip
=> Paperclip
Hope this helps

You can require them manually like Daniel posted, and you can also require them automatically. You need to add dependencies in 3 files:
yourengine.gemspec
s.add_dependency "rails", '4.1.0'
s.add_dependency "sqlite3"
Gemfile
# Imports dependencies from yourengine.gemspec
gemspec
lib/yourengine.rb
# requires all dependencies
Gem.loaded_specs['yourengine'].dependencies.each do |d|
require d.name
end
require 'yourengine/engine'
module Yourengine
end
Update: It's a simplistic demonstration of how to require the dependencies. You should test it and filter unwanted items, for example: require d.name unless d.type == :development (thx #imsinu9)

from paperclip's README :
For Non-Rails usage:
class ModuleName < ActiveRecord::Base
include Paperclip::Glue
...
end
I had the same issue and that fixed it for me.

You must add the gem file to both the .gemspec file, and your engine.rb file.
In the .gemspec file it would be like:
s.add_dependency "kaminari", "0.16.1"
In the engine.rb file at the top add:
require "kaminari"
I think you also need to add the gem to the rails engine Gemfile and bundle install, but I'm not certain if you need it there.

At the time being (Rails 3.1 and above I think), you shouldn't have do declare any gems in the test/dummy/Gemfile anymore:
Quote from test/dummy/Gemfile (generated using rails plugin new my_engine --full):
Declare your gem's dependencies in simple_view_helpers.gemspec.
Bundler will treat runtime dependencies like base dependencies, and
development dependencies will be added by default to the :development group.
Declare any dependencies that are still in development here instead of in
your gemspec. These might include edge Rails or gems from your path or
Git. Remember to move these dependencies to your gemspec before releasing
your gem to rubygems.org.

You really shouldn't need them on the Gemsec, and they should be loaded. When you say "here is the gemspec", you are surrounding it with Gem::Specification.new do |s| or something to that effect, right?

You can include all gems for the environment with a simple bundler command:
Bundler.require(*Rails.groups)
You could add this to an config/initializer.

Related

Use Haml files in Redmine plugin

I am creating a Redmine plugin and would like to use Haml for the view templates. There is an existing plugin which has Haml views (ekanban) and it does not contain any special code to get Haml working other then having you add require 'haml' to your main application's Gemfile.
So here is what happens -- the templating system loads the .html.haml file correctly but renders the HAML markup (like it was rendering ERB).
I've tried to insert the require 'haml' at various intervals to no avail. I've even tried manually trying to activate Haml.init_rails(...) as suggested in this SO question. I've tried inserting that in a few places, tried it in a Rails.configuration.to_prepare block in the plugins' init.rb file. I've tried telling the Gemfile to not require 'haml' and attempting to do it during plugin load to no avail. What gives?
The view template had Textile in it and I did not notice because the markup for <h2> is similar (h2. vs. %h2). Including gem 'haml_rails' in the plugin's Gemfile is sufficient with no extra code.
Read carefully Installation instruction for this gem :)
Add "gem 'haml'" to your #{RAILS_ROOT}/Gemfile
I can't agree with this strategy: plugin can't change Redmine core! Any Redmine plugin can have own gems (defined in own Gemfile) - so I think you can create Gemfile in your plugin, run bundle install from the Redmine root and I believe you will manage to use Haml

Twitter bootstrap: do I need both bootstrap-sass and twitter-bootstrap-rails gems?

I have the following entries my (Rails 3.2.13) Gemfile:
gem 'twitter-bootstrap-rails'
gem 'bootstrap-sass'
and in app/assets/javascripts/application.js:
//= require twitter/bootstrap
and at the top of app/assets/stylesheets/custom.css.scss:
#import 'bootstrap'
Is this "correct"? Do I need both 'twitter-bootstrap-rails' and 'bootstrap-sass' (or maybe 'bootstrap-sass-rails'), or are they redundant and possibly conflicting? Do the 'bootstrap-sass' gems include the javascript for the framework, or only the CSS?
No you do not need both.
Just simply put this in your gemfile:
gem 'sass-rails'
gem 'bootstrap-sass'
This in application.css.scss:
#import 'bootstrap';
#import 'bootstrap-responsive';
This in application.js
//= require bootstrap
If you're still having problems you may need to look at the ordering of things in your manifest files..
If you want to use SASS you should use boostrap-sass or bootstrap-sass-rails. Twitter-bootstrap-rails uses LESS source. If you were to include both there would probably be conflicts. All of them include javascript for bootstrap already and integrate into the asset pipeline.
I personally use LESS version as it is what bootstrap is originally written in. (might get faster releases when bootstrap updates)
It's generally good to check the gems out on github to evaluate your exact needs and which version of Rails they support.

How to use SASS, HAML, and CoffeeScript in Rails 3.2.x Engine?

Currently, I have a Rails 3.2.9 Engine which is using sass-rails. When I generate a controller with a couple actions, the assets are also generated (i.e., javascript and CSS). However, both the Javascript and SASS are *.js and *.css files. They're not CoffeeScript (*.js.coffee) or SASS (*.css.sass). Any ideas how to get this work?
Here's a different solution which will use the coffee-rails and sass-rails gems by default - also fixes haml-rails.
I added this to the top of my engine.rb file:
require 'rails'
require 'coffee-rails'
require 'sass/rails'
require 'haml-rails'
What I did was inspect the source code of these files to see how they work in a normal Rails application. For example, in haml-rails I looked at lib/haml-rails.rb and saw the following:
require 'haml'
require 'rails'
module Haml
module Rails
class Railtie < ::Rails::Railtie
if ::Rails.version.to_f >= 3.1
config.app_generators.template_engine :haml
else
config.generators.template_engine :haml
end
...
Similar files exist for sass-rails (lib/sass/rails/railtie.rb) and coffee-rails (lib/coffee/rails/engine.rb).
Just append --stylesheet_engine=sass --javascript_engine=coffee to your generator command (I'm assuming rails g controller).

#import "compass" breaking in asset pipeline rails 3.2.1

I have an application.sass inside app/assets/stylesheets and it has in it:
#import "compass"
When I attempt to launch my development webserver, I get:
Error compiling CSS Asset
Sass::SyntaxError: File to import not found or unreadable: compass.
I am using compass-rails-1.0.0.rc.2 with compass-0.12.rc.1
This probably isn't your problem, but I just ran across the same error message and spent WAY too long trying different versions of compass/compass-rails, thinking it wasn't my fault.
The problem turned out to be that my application.css file wasn't getting run through the sass preprocessor. So I renamed it to application.css.scss and bang! Yours is named .sass, you could check by renaming it to .css.sass, or .css.scss (just to test) and see if you get different results.
Are you upgrading from a pre-asset pipeline version of Rails (e.g. 3.0)? Please make sure that you are requiring the assets group when initializing bundler in your application.rb.
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
Otherwise, for compass to work in development, compass-rails and sass-rails must be outside of the assets group in your Gemfile.

Asset pipeline won't even try to compile SASS

My setup is fairly simple default rails 3.2.1 setup. All my .css.sass files are in /app/assets/stylesheets/. I have the sass-rails '~> 3.2.3' gem in :assets group.
There's no application.css, just main.css.sass (used for main layout).
When i issue:
RAILS_ENV=production bundle exec rake assets:precompile
it compiles my coffeescripts and javascripts. There are no error messages in the log. It's like it doesn't even try to compile sass files.
The main.css.sass file header looks like this:
//=depend_on "_globals.css.sass"
#import globals
The _glocals.css.sass exists in the same directory.
James is right and it's one of the possible solutions.
The drawback of adding all files to one manifest file is that all will be precompiled to single file - which isn't always what you want.
In my case I needed separate files (one file for each layout).
Heres how to add new manifest files:
config.assets.precompile += %w( file1.css file2.css )
You don't need to have actual file1.css, if you have file1.css.sass it will be precompiled.
I think sass needs a manifest file and by default that's application.css for a rails 3.2 app. So creating application.css and //= require 'main' might dove your problem.