While browsing through the active-admin code, I found that Gemfile contains the rails entry.
rails_version = detect_rails_version
gem 'rails', rails_version
Does that mean active-admin internally creates a rails server which is not the main rails app?
If Yes, will that lead to performance issues and using it with complex rails applications is a bad practice?
if No, what is the use of it in active-admin Gemfile?
Googled a lot with different keywords which only leads to gem install and related results.
I would be glad if somebody put some insights. Thanks :)
update1: After Gaurish answer and googling, it seems that Gemfile inside gem is used to list dependencies needed for gem internally. But it create another question, what happens when application gems and gems' gem conflits?
update2:
Can we use active-admin standalone, since it has rails as a dependency? (Just installing active-admin by gem install active-admin
instead of keeping it in some other rails application.)
No. This seems a bundler issue. this code just declares a dependency on rails. sound's strange? Here is what I think is happening.
the usual way is to declare your dependencies in .gemspec
file by using following line:
s.add_dependency("rails", ">= 3.0.0")
the above lines add a dependancy on rails v3.0
& above(v3.1
,v3.2
). now this works fine for other gems & bundler will auto resolve dependencies. But when you try to support multiple versions of rails, bundler might get confused.
Ideally, bundler should be able to automatically bundle(install) all the dependencies of our gem. And also dependencies of gem dependencies. example, bundle should be smart enough to figure out if rails v3.1
or v3.2
is required, it also needs to include sass-rails
& 'uglifier' as they required by rails 3.1 & 3.2. But if rails v3.0
is required, nothing extra need to be done.
But we live in not so perfect world, so bundler is not smart enough. Hence, I think this is the reason active-admin
has to resort to the following hack around bundler's shortcomings.
unless defined?(RAILS_VERSION_FILE)
RAILS_VERSION_FILE = File.expand_path("../../../.rails-version", __FILE__)
end
unless defined?(DEFAULT_RAILS_VERSION)
DEFAULT_RAILS_VERSION = "3.1.0"
end
def detect_rails_version
return DEFAULT_RAILS_VERSION unless File.exists?(RAILS_VERSION_FILE)
File.read(RAILS_VERSION_FILE).chomp
end
def write_rails_version(version)
File.open(RAILS_VERSION_FILE, "w+"){|f| f << version }
end
rails_version = detect_rails_version
gem 'rails', rails_version
case rails_version
when /^3\.0/
# Do nothing, bundler should figure it out
when /^3\.(1|2)/
# These are the gems you have to have for Rails 3.1 to be happy
gem 'sass-rails'
gem 'uglifier'
else
raise "Rails #{rails_version} is not supported yet"
end
if you notice the above code, it checks if current version of rails is v3.1 or v3.2. if yes, then add new two as dependencies. That's all this code does.
[Update]
Questions 1. what happens when application gems and gems' gem conflicts? If they conflict in such a way that bundler can't find a compatible version that satisfies dependencies of your app and gems. bundler will fail with an error something similar to this:
Bundler could not find compatible versions for gem "json":
In Gemfile:
chef (~> 10.26) ruby depends on
json (<= 1.7.7, >= 1.4.4) ruby
berkshelf (~> 2.0) ruby depends on
json (1.8.0)
Question 2. Can we use active-admin standalone
without rails? No. when you do gem install active-admin
, rubygems will auto install rails as its listed as a dependency of this gem in gemspec
file.