Hello I am new to Rails Engine , I have followed ruby official documentation for "Creating Rails Engine" http://guides.rubyonrails.org/engines.html After creating Plugin I have added plugin name in gemfile to load the engine
gem 'product_search', :path => 'product_search/engines/product_search'
but it always through error The path /var/www/sites/web_service/product_search/engines/product_search does not exist.
The Plugin name is "ProductSearch"
I have also changes the pathname
gem 'product_search', :path => 'ProductSearch/engines/product_search'
[It is the Directory structure of the plugin:]
http://i.stack.imgur.com/hRh1X.png
Thanks in advance..!!!
From the documentation:
At the root of this brand new engine's directory lives a
blorgh.gemspec file. When you include the engine into an application
later on, you will do so with this line in the Rails application's
Gemfile:
gem 'blorgh', path: "vendor/engines/blorgh"
Don't forget to run bundle install as usual. By specifying it as a gem
within the Gemfile, Bundler will load it as such, parsing this
blorgh.gemspec file and requiring a file within the lib directory
called lib/blorgh.rb. This file requires the blorgh/engine.rb file
(located at lib/blorgh/engine.rb) and defines a base module called
Blorgh.
Related
I've been following the guide around rails engines here: http://guides.rubyonrails.org/engines.html and have created the example engine blorgh and also have a barebones rails app.
I generated my engine following this command:
rails plugin new blorgh --mountable
And I can confirm that I have: /lib/blorgh.rb in my engine. Now going by the guides it states you simply need to add the following to your main app:
gem 'blorgh', path: 'engines/blorgh'. Now in my main rails app when I try to do bundle install I get:
The path /Users/home/projects/unicorn/engines/blorgh does not exist.
I'm pretty sure I'm missing something basic here.
The path /Users/home/projects/unicorn/engines/blorgh does not exist
Because Rails application going to Search ‘engines’ folder that's stores the engines (even if you just have one!) in your case /engines/blorgh not found any engine.
The path option in Gemfile is for using gem that is on the path specified.
And it have to be the directory where the unpacked gem is located.
In your case it looked to engines/blorgh relative to your working directory. Which is on /Users/home/projects/unicorn/engines/blorgh.
And /Users/home/projects/unicorn/engines/blorgh is simply doesn't exists.
To fix it, make sure you put the engine on /Users/home/projects/unicorn/engines/blorgh
I'm creating a gem (let's call it mygem) that is essentially a Sinatra server intended to be mounted within Rack based apps.
Inside my gem's gemspec file, I have the following:
gem.add_dependency 'kss'
And Inside my gem's Gemfile, I have the following
source 'https://rubygems.org'
gemspec
gem "kss", :path => "/Users/me/code/kss"
Now when running the server from within mygem's folder, this works exactly as expected: instead of fetching out for the kss dependency, it will look on my local drive and load that version.
The problem comes in when I add mygem to a Rails test app Gemfile. In my Rails test app Gemfile, I have the following line:
gem "mygem", :path => "/Users/me/code/mygem"
I would expect, upon a bundle install, that Bundler would load mygem and its dependencies; but for the kss dependency, instead of loading the local dependency, Bundler actually does fetches out to rubygems to find and load it. I'm assuming because in this case, it's only reading from the gemspec line and not including my dependency override.
Is there anything I can do to fix this behavior? I'd very much like to be able to run and test this stuff locally, but Bundler doesn't seem to recognize dependency overrides from a higher level app.
I'm completely open to any suggestions or changes if I'm going about this the wrong way.
Dependencies listed in your gemspec will become dependencies of the implementing application, while dependencies defined in the Gemfile will not become dependencies of the implementing application. I think you should be able to simply adjust the Rails test app Gemfile to be:
gem "kss", :path => "/Users/me/code/kss"
gem "mygem", :path => "/Users/me/code/mygem"
I'm not sure if this sort of thing is very common, but I keep finding myself trying to create gems that are just wrappers around a Rails application.
My gem will have a generator to create a config.ru but the Rails application will live inside the gem's lib directory. I need to know how to "embed" a Rails application and configure it so that it can be run inside the gem.
For example:
$ mygem new project
mygem created a directory called "project" with the following files:
project/config.ru
project/widgets/
project/foobars/
My gem will also generate some directories that will need to be added to Rails somehow so that I can access the code in those directories from the Rails app living inside the Gem.
Any help or advice you can give me would be appreciated.
To clarify, I'm not trying to create a Rails engine, or plugin to a Rails application. I'm trying to create a fully-fledged Rails application, but package it as a gem so that a user of my gem can run the gem (the rails app) without needing to know that it's using Rails behind the scenes.
Update: Okay, I've got a little bit working now. I've created the gem and generated the rails project inside the gem's lib directory.
$ bundle gem my_gem && cd my_gem/lib
$ rails new my_gem --skip-bundle
Which leaves me with:
my_gem/
my_gem.gemspec
bin/my_gem
lib/
my_gem.rb
my_gem/
version.rb # generated by bundler
# the rails app:
app/
config/
Gemfile
...etc
Since this gem requires Rails, I started adding the gems defined in the Rails Gemfile as dependencies in the gem's Gemspec, but I'm a little confused as to how to handle the assets group in the Gemfile.
# Rails Gemfile
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'therubyracer', :platforms => :ruby
gem 'uglifier', '>= 1.0.3'
end
# gemspec
Gem::Specification.new do |gem|
gem.name = "my_gem"
# ...
gem.add_dependency 'rails', '3.2.8'
gem.add_dependency 'sqlite3'
gem.add_dependency 'jquery-rails'
# how to add the assets group gems?
end
Try this and see if it helps you make progress.
Gems are just directories of files, and you can put whatever files you want into a gem.
Create:
Create a blank gem full-blown Rails project:
$ bundle gem my_gem
Then a Rails app:
$ rails new my_app --skip-bundle
Copy the Rails files into the gem:
$ cp -R my_app/* my_gem
Bundle everything into your Rails app:
$ cd my_gem
$ bundle install --binstubs --path vendor/bundle
$ cd -
Make the Rakefile have the gem tasks and the Rails setup:
#!/usr/bin/env rake
require "bundler/gem_tasks"
require File.expand_path('../config/application', __FILE__)
MyApp::Application.load_tasks
Verify that it starts:
$ rails server
Load Path:
To control where Rails looks for files, such as "external" configuration files, you can use the file config/application.rb with any directory paths like this:
# Add additional load paths for your own custom dirs
# config.load_paths += %W( #{config.root}/../customdir )
Note the ".." which means go above the Rails directory. This gives you a path relative to the gem.
If you prefer you can specify an absolute path, for example if you know the user will always keep his external files in "~/myfiles/". You can also choose to use ENV vars to send in whatever directory you want.
If you read about load path capabilties, look for lines that are shorthand for adding a directory to the front of the load path because you may want to put your external diretories first:
$:.unshift File.dirname(__FILE__)
Gem Build:
Edit my_gem.gemspec to add your own description, homepage, summary, etc. then build:
$ gem build my_gem.gemspec
Successfully built RubyGem
Name: my_gem
Version: 0.0.1
File: my_gem-0.0.1.gem
Now your Rails app is packaged as a gem.
The config.ru should be a typical Rails one. No special changes AFAIK.
When your user wants to install your app:
$ gem install my_gem
The gem will install in the user's typical gem directory. If you want to adjust this, see this page on rubygems: http://docs.rubygems.org/read/chapter/3
Crate:
You may also want to investigate the Crate project:
Crate: Packaging Standalone Ruby Applications
http://www.slideshare.net/copiousfreetime/crate-packaging-standalone-ruby-applications
Rack:
To use config.ru here is the typical Rails setup:
# Rails.root/config.ru
require "config/environment"
use Rails::Rack::LogTailer
use ActionDispatch::Static
run ActionController::Dispatcher.new
For your project, you want to require some files before Rails. You'll want to learn about the Ruby "require" and how it finds files using LOAD_PATH.
The easy way:
# Rails.root/config.ru
require_relative 'filename'
require "config/environment"
Or to put the user's custom directory up couple directory levels:
require './../../filename' # not the best for security
Or to use an absolute path, read about File.expand_path:
File.expand_path(__FILE__)
Or to use the current directory and put it on the load path:
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'filename'
Lots of choices for you to consider. Hope this helps!
What about the question, "How am I going to run the Rails application inside the gem?".
A Rails application has controllers and views to run a web server. What you need are actions to create, list, update, and destroy. Exposing these actions without a web server is essentially having such methods in a class. That's a normal standard type of gem in the first place.
So maybe your questions is really, how do I write a gem where I have ActiveRecord, and the other Rails stuff.
First, you need to make your gem dependent on the Rails gems you need. You do this in the gemspec file for your gem.
Then it really is just a matter of your gem code doing a require of the right Rails gems you need.
I'm not sure if this will help, as I read through everything and I couldn't find the motivation behind why you were doing this. One of the reasons I came up with was making something that can be used on a desktop environment. In that case you could try using something like Bowline. If you just want to provide an application that others can download and use and install themselves, then you can probably assume they can follow at least basic developer kind of instructions and you could just provide the whole app on github or as a zip file. See an example of someone else doing something similar over on Fat Free CRM's github page.
I created a custom gem called pdf2html. The gem file is pdf2html-0.1.gem
I placed this file in the vendor directory of rails 3 project.
My Gemfile entry for this gems reads as follows
gem 'pdf2html', '0.1' , :path => 'vendor'
When I run the bundle install command I get the following message regarding this gem
* pdf2html at `vendor` will not be cached.
I tried doing a bundle show on this gem it tells me that it is installed in the vendor directory.
Now when I do a rails console and try to do a require 'pdf2html' I get a "No such file to load error"/
Can someone tell me what I am doing wrong
Thanks
Paul
I thought the proper way to declare gems was to specify the full path, not the base path, as in:
gem 'pdf2html', '0.1', :path => 'vendor/pdf2html'
The reason it doesn't error out sooner is that the path vendor/ actually exists so there's no immediate problem. It's only when you try to require vendor/pdf2html.rb, which is missing, that there's an issue raised.
I pushed the gem and associated files over to github and then installed it from there using the Gemfile/ bundle install. Now its working fine. I could not figure out how to use the local gem file
Let's say I have created a mountable engine into ~/my_engine folder:
rails plugin new my_engine --mountable
How do I mount this engine into a Rails 3.1 app, that is at the same directory level (e.g. ~/my_app)?
There is a good writeup of the process here:
http://www.builtfromsource.com/2010/12/13/mountable-engines-in-rails-3-1-beta-getting-started/
In short, add this to your main app's Gemfile:
gem 'my_engine', :path => '../my_engine'
And run bundle install/bundle update. Add this to your main app
mount MyEngine::Engine => '/my-engine-url'