Rails gem developement coping resources to the application - ruby-on-rails

In my gem (myEngine.rb) I have the following code :
require "myEngine/version"
require "myEngine/models/contact"
require 'rails/generators'
module myEngine
def self.generate_migration
file_name= "migrationSrc.rb"
src_path= "myEngine/migration_files/"+file_name
destination_path= "db/migrate/"+file_name
//
end
end
When I call the method generate_migration I want my gem to copy the migration file to the db/migrate of my application.
Thanks you for your help.

Related

Ruby Gem Project -- Thor Generator Causing Read-only File System Error

As a personal project, I decided to write a minified-version of Ruby on Rails and upload it as a gem using Bundle called railz_lite.
Inside of my project, I was hoping to implement a Generator similar to rails new, which would create the necessary folders for a web app i.e. controllers/, views/, models/, etc.
To do so, I included Thor as a dependency, then created the following files:
require 'thor/group'
module RailzLite
module Generators
class Project < Thor::Group
include Thor::Actions
def self.source_root
File.dirname(__FILE__) + "/templates"
end
def add_controllers
empty_directory("controllers")
end
def add_models
empty_directory("models")
end
def add_server
template("server.rb", "config/server.rb")
end
def add_views
empty_directory("views")
end
def add_public
empty_directory("public")
end
end
end
end
Inside the gem project's root folder, when I run bundle exec railz_lite new, the generator works just fine and the necessary files are created.
However, if I create a new project, puts my gem (railz_lite) in the Gemfile, run bundle install, then execute bundle exec rails_lite new, I am greeted with the following error:
.rbenv/versions/2.5.1/lib/ruby/2.5.0/fileutils.rb:232:in `mkdir':
: Read-only file system # dir_s_mkdir - /controllers (Errno::EROFS)
I suspect the error is because the empty_directory command is not referring to the root directory of the project I just created. I am hoping that there is a simple way to fix this.
For further reference, the CLI script and class look as follows:
railz_lite
#!/usr/bin/env ruby
require 'railz_lite/cli'
RailzLite::CLI.start
cli.rb
require 'thor'
require 'railz_lite'
require 'railz_lite/generators/project'
module RailzLite
class CLI < Thor
desc 'new', 'Generates a new RailzLite project'
def new
RailzLite::Generators::Project.start([])
end
end
end
Any solutions would be greatly appreciated!
Note: I am running this on macOS Catalina.
So I found a solution after searching extensively through gem forums and looking at the Rails source code.
Inside of the generation I have to manually set the destination_root to the working directory of the project. The working directory can be found with Dir.pwd
require 'thor/group'
module RailzLite
module Generators
class Project < Thor::Group
include Thor::Actions
def self.source_root
File.dirname(__FILE__) + "/templates"
end
def self.destination_root # this method fixes the problem!
Dir.pwd # get the current project directory
end
def add_controllers
empty_directory("controllers")
end
def add_models
empty_directory("models")
end
def add_server
template("server.rb", "config/server.rb")
end
def add_views
empty_directory("views")
end
def add_public
empty_directory("public")
end
end
end
end

Rails engine extends config/application.rb

I am in the process of writing a Rails engine but i am not sure how to extend my the config/application.rb
I guess i have to get to the application name somehow
any ideas?
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env)
module application_name
class Application < Rails::Application
end
end
For a --full and --mountable engine
This will be generated for you.
module engine_name
class Engine < ::Rails::Engine
end
end
In you main applications gemfile add
gem 'engine_name', path: "/path/to/engine_name"
And in your applications config/routes.rb file
mount engine_name::Engine, at: "/<mount_point_you_choose>"
http://guides.rubyonrails.org/engines.html
Taken from the link above...
The --mountable option tells the generator that you want to create a "mountable" and namespace-isolated engine. This generator will provide the same skeleton structure as would the --full option, and will add:
Asset manifest files (application.js and application.css)
A namespaced ApplicationController stub
A namespaced ApplicationHelper stub
A layout view template for the engine
Namespace isolation to config/routes.rb:

Cannot find file or constant when using a gem locally in a Rails app

I have a gem that I am making and it is located at the same level as a rails app.
I am trying to use the gem in the rails app, but am not able to make it work - the constant I am trying to use, which is defined in the gem, is not accessible to the rails app for some reason.
What am I doing wrong here? What steps can I take to begin debugging the cause of the problem?
In the rails console, $:.grep /mygem/ shows me ["/Users/zabba/mygem/lib"]
Directory structure, with the contents of certain files:
~/mygem/
lib/
mygem/
some_class.rb
module Mygem
class SomeClass
end
end
mygem.rb
require 'mygem/some_class'
~/railsapp/
Gemfile:
gem 'mygem', path: '../mygem', require: 'mygem'
app/
models/
a_model.rb:
# require 'mygem' cannot find file
class AModel
def hello_world
SomeClass.new # Cannot find constant
Mygem::SomeClass.new # Cannot find constant
end
end
Can you create a folder vendor/gems and copy your gem in there. Then in you Gemfile
Gemfile
gem 'mygem', :path => "vendor/gems/mygem-0.0.1"
Then bundle install

Gem not working in rails project but in ruby file

When I run test.rb (see below) as a separate ruby file from within my rails project it works fine but when I wrap it as a module to be called from a controller it gives me:
LoadError (no such file to load -- eventmachine):1 in 'ModuleTest'
The gem is installed (sudo gem install event machine and bundle install) and added to the gem file (gem 'eventmachine').
Could someone please advice on what it is that I'm missing?
Separate file (called through: $ ruby lib/test.rb):
require 'rubygems'
require 'eventmachine'
require 'em-http'
require 'fiber'
def doStuff
end
doStuff
Module:
require 'eventmachine'
require 'em-http'
require 'fiber'
module ModuleTest
def doStuff
end
end
Controller:
require 'moduletest'
class MyController < ApplicationController
doStuff
end
Add
gem 'eventmachine'
Into your Gemfile. Then execute bundle install.
If you want to use a new gem in your rails project, you need to add it into Gemfile. To learn more, visit http://gembundler.com/

Rails 3 generators in gem

Might sound like a simple question, but I'm stumped.
I've created a gem that essentially contains a generator.
It contains the following structure:
lib
- generators
- my_generator
my_generator_generator.rb (see below)
- templates
my_template_files...
- my_generator.rb (empty file)
test
-test files
GemFile
etc..
However when I add this Gem to my gem file and run rails g, it's not listed. Is there any additional config that I need to do?
My generator roughly looks like this...
class MyGeneratorGenerator < Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)
generator code....
end
The strange thing is, it works in Cygwin, but not in Ubuntu...
This took a little bit for me to figure out, but I've run into the same problem. Here is how I fixed it.
Tree structure looks like this:
lib
- generators
- gemname
install_generator.rb
- templates
(template files)
Here's the code for install_generator.rb
#lib/generators/gemname/install_generator.rb
require 'rails/generators'
module Gemname
class InstallGenerator < Rails::Generators::Base
desc "Some description of my generator here"
# Commandline options can be defined here using Thor-like options:
class_option :my_opt, :type => :boolean, :default => false, :desc => "My Option"
# I can later access that option using:
# options[:my_opt]
def self.source_root
#source_root ||= File.join(File.dirname(__FILE__), 'templates')
end
# Generator Code. Remember this is just suped-up Thor so methods are executed in order
end
end
When I run
rails g
I see:
Gemname
gemname:install
Some other things you may need to setup:
#lib/gemname.rb
module Gemname
require 'gemname/engine' if defined?(Rails)
# any additional requires
end
and
#/lib/gemname/engine.rb
require 'rails'
module Gemname
class Engine < Rails::Engine
end
end
Some good references I've found on this are:
http://textmate.rubyforge.org/thor/Thor.html (take a look at the modules, especially Thor::Actions)
http://api.rubyonrails.org/classes/Rails/Generators/Base.html
http://api.rubyonrails.org/classes/Rails/Generators/Actions.html
https://github.com/wycats/thor/blob/master/README.md
http://www.themodestrubyist.com/2010/03/16/rails-3-plugins---part-3---rake-tasks-generators-initializers-oh-my/
If you use Railtie, you can define your generator wherever it could be using:
generators do
require "path/to/my_railtie_generator"
end
in Railtie class.

Resources