I have a Rails project at work that I'd like to try Solargraph on, but I don't want to add it into the Gemfile. Are there any other ways?
Here's my .solargraph.yml:
include:
- "**/*.rb"
exclude:
- spec/**/*
- test/**/*
- vendor/**/*
- ".bundle/**/*"
require:
- rails
domains: []
reporters:
- rubocop
- require_not_found
plugins: []
require_paths: []
max_files: 5000
I have the Rails methods available due to rails being in the require section, but I'd very much like to avoid requiring every gem in the Gemfile manually...
Running Solargraph without Bundler shouldn't be a problem as long as Ruby can find the gems that your application requires. You may run into caveats if your application uses a gem cache or your Gemfile specifies a different version of the gem than the one Ruby finds.
At the moment, Solargraph can only find gems that are explicitly require'd, either in the application's code or in the require section of .solargraph.yml. (There's a Rails-specific example of this method in #87). I'm working on ways to improve on that; for example, if your code calls require 'bundler/require' or Bundler.require (as Rails apps do), Solargraph should automatically add all your gem dependencies to its maps.
I'm also working on ways to improve Rails integration in particular. One solution I've found is to use a @!parse directive. I added this block to a file in the root called definitions.rb:
# @!parse
# require 'actioncable'
# require 'actionmailer'
# require 'actionpack'
# require 'actionview'
# require 'activejob'
# require 'activemodel'
# require 'activerecord'
# require 'activestorage'
# require 'activesupport'
# class ActiveRecord::Base
# extend ActiveRecord::QueryMethods
# extend ActiveRecord::FinderMethods
# extend ActiveRecord::Associations::ClassMethods
# end
nil
With proper handling of Bundler.require, those explicit requires should no longer be necessary. The class ActiveRecord::Base definition is necessary for Solargraph to recognize some of the runtime magic involved in composing model classes. It's still far from perfect, but it's another step closer.
(Note: the nil after the comment block is a temporary hack that should be resolved in the next patch release of the gem.)
@castwide thanks for the example! I noticed the class ActiveRecord::Base part is missing from the .solargraph.yml config in #87. Is that only workable with the @!parse directive, or could we add a line in the domains section of the config to get the same behavior?
The @!parse directive is currently the best way to handle it. The config's domains section (along with the custom @!domain directive) is intended to expose a class/module's public methods as a DSL. It wouldn't work correctly for the ActiveRecord::Base issue.
Most helpful comment
Running Solargraph without Bundler shouldn't be a problem as long as Ruby can find the gems that your application requires. You may run into caveats if your application uses a gem cache or your Gemfile specifies a different version of the gem than the one Ruby finds.
At the moment, Solargraph can only find gems that are explicitly
require'd, either in the application's code or in therequiresection of.solargraph.yml. (There's a Rails-specific example of this method in #87). I'm working on ways to improve on that; for example, if your code callsrequire 'bundler/require'orBundler.require(as Rails apps do), Solargraph should automatically add all your gem dependencies to its maps.I'm also working on ways to improve Rails integration in particular. One solution I've found is to use a
@!parsedirective. I added this block to a file in the root calleddefinitions.rb:With proper handling of
Bundler.require, those explicit requires should no longer be necessary. Theclass ActiveRecord::Basedefinition is necessary for Solargraph to recognize some of the runtime magic involved in composing model classes. It's still far from perfect, but it's another step closer.(Note: the
nilafter the comment block is a temporary hack that should be resolved in the next patch release of the gem.)