Solargraph and Rails
Ruby on Rails uses a lot of “magic” that makes it difficult, but not impossible, to gather code intelligence through static analysis. This page explains the current progress and provides some tips for improving Solargraph’s intellisense features in Rails projects.
Quick Start
There are two simple steps that should partially improve intellisense with Rails:
- Run
solargraph bundle
from your Rails project’s root directory. - Add the most recent version of this file to the project: https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e
Documenting Gems with solargraph bundle
The gems at the core of Rails (actionpack, activerecord, etc.) contain little to no YARD documentation. They generally use RDoc syntax instead. In order to make the most use of the existing documentation, solargraph bundle
creates a special documentation cache that gets generated from RDoc and converted to YARD. Solargraph has a whitelist of Rails-related gems that require this alternative. Any other gems receive the usual YARD documentation.
The Comment File
The code in the gist should be added as a Ruby file somewhere that makes it visible to Solargraph, e.g., a file named definitions.rb
in the config
directory. Since the file only contains comments, Solargraph will process it but it has no impact on the runtime. The comments contain YARD directives that fill some of the gaps in Solargraph’s understanding of the Rails app.
This section, for example, exposes some of the ActiveRecord methods that are defined at runtime but are not discoverable through static analysis:
# @!parse
# class ActiveRecord::Base
# extend ActiveRecord::QueryMethods
# extend ActiveRecord::FinderMethods
# extend ActiveRecord::Associations::ClassMethods
# include ActiveRecord::Persistence
# end
The custom @!override
directive allows you to inject your own YARD tags into external methods. This example applies overloads to ActiveRecord::FinderMethods#find
so your models can infer the correct types from your models’ find
methods:
# @!override ActiveRecord::FinderMethods#find
# @overload find(id)
# @param id [Integer]
# @return [self]
# @overload find(list)
# @param list [Array]
# @return [Array<self>]
# @overload find(*args)
# @return [Array<self>]
# @return [self, Array<self>]
Rails support is very much a work in progress. If you have any questions or comments, please post them to the gist or the related GitHub issue.