Conditional ruby gem dependencies within a gemspec
To access rails version, we can use something like below (based on this answer):
require 'rubygems'
rails_gem = Gem::Specification.select {|z| z.name == "rails"}.max_by {|a| a.version}
p rails_gem.version.version
#=> "4.2.5"
How to create a Rails gem with conditional dependency installation
I wasn't able to really figure out the dependency injection for now. So I tried to take what @engineersmky suggested and created an install for the gems. So for right now I have this as my install generator
require 'generators/base_generator'
module MyGem
module Blueprinter
class InstallGenerator < BaseGenerator
source_root File.expand_path("../../../templates", __FILE__)
# Add blueprinter gem to gemfile after my_gem declaration and bundles the newly declared gem
def install_blueprinter
remove_other_supported_gems('ActiveModelSerializers', 'FastJsonapi')
puts 'Installing Blueprinter...'
insert_into_file('Gemfile',
"\ngem 'blueprinter'",
after: "gem 'dry_serialization', source: 'https://gem.fury.io/my_private_gems/'")
run 'bundle install'
end
def helper_include
copy_api_controller
gsub_file(API_CONTROLLER_PATH, /^\t*(include MyGem::.*)\n/, '')
puts 'Adding include statement to ApiController'
insert_into_file(API_CONTROLLER_PATH,
"\n\tinclude MyGem::Blueprinter",
after: 'class ApiController < ActionController::API'
)
end
end
end
end
Gets called with rails g my_gem::blueprinter::install
This creates an ApiController that inherits from ActionController::Base unless one already exists, inserts gem 'blueprinter'
into the gemfile after my_gem's declaration, removes references to other serializer gems, then bundles to install the gem.
I like to separate my controllers into api and application to separate the concerns if I decide on a monolith app :D
Then you can use the dryed up methods that I'm creating in each file for each respective gem :D
Conditional gem dependencies
Hmm,
I believe one can code multiple dependencies because I've noticed gems which seemed to do this. But I would you advise against doing this. No matter how simple the code you are inserting here is, when you consider that the user will be loading one gem which depends on another which depends on another, even a small glitch in the logic of one piece of code or another can make the whole dependency train a nightmare.
So, I'd leave your kludge as-is. Further, I'd suggest you have a tarball that users can download as well. I've had to manually extract the code inside of gems whose configuration code wouldn't let me install them.
Conditional Dependency in Ruby Gemspec
Yes, I would suggest a simple text requirement in spec.requirements
. I would also recommend some sort of load-chaining when the gem first loads:
# in init.rb and/or rails/init.rb:
unless Object.const_defined?(:JSON)
begin
require 'json_pure'
rescue LoadError
begin
require 'json-ruby'
rescue LoadError
require 'json'
end
end
end
unless Object.const_defined?(:JSON)
raise "Could not load gem MyGem; did you install one of json_pur, json-ruby, or the C-based json library?"
end
Related Topics
How to Reference a Method in Another Ruby Code File
Specifying Content Type in Rspec
Saml 2.0 Sso for Ruby on Rails
Ruby on Rails: How to Use Oauth2::Accesstoken.Post
How to Connect to Browser Using Ruby Selenium Webdriver
Get Response Headers from Curb
Where to Put a Before_Filter Shared Between Multiple Controllers
Ruby: How to Check If a String Contains Multiple Items
Ftps (Tls/Ssl) from Ruby on Rails App
Ruby Scope of Data After _End_
How to Convert Activerecord Table Name to Model Class Name
How to Get a List of Gems That Are Installed That Have Native Extensions
Pg_Config, Ruby Pg, Postgresql 9.0 Problem After Upgrade, Centos 5
Rails Initializes Extremely Slow on Ruby 1.9.1
Rails: Detecting User Agent Works in Development But Not Production
How to Extend Redcarpet to Support Auto Linking User Mentions
Rails 4.0.3 Generating Incorrect Asset Paths with Asset_Sync