I know Rails support is only partial at the moment, but I have installed the Solargraph gem, and am using the VSCode extension, and when I am in a Rails application, I am not getting any Rails-related completions/suggestions whatsoever.
I don't even get a suggestion for the "Rails" class. I just want to make sure I am not getting the wrong end of the stick in terms of what amount of Rails support Solargraph actually has? Solargraph itself is working fine - I am getting standard Ruby suggestions no problem.
There are a couple of things you can try.
Make sure you have gem documentation installed by running yard gems.
Add a .solargraph.yml file to the app's root directory (you can generate a default one by running solargraph config) and make the following change to the require section:
require:
- actioncable
- actionmailer
- actionpack
- actionview
- activejob
- activemodel
- activerecord
- activestorage
- activesupport
That should get you closer, but it's still far from perfect. Improving Rails support has been on the roadmap for a while. The amount of runtime magic involved makes it challenging, but I have some updates in the works that should help.
I hope it's fine if I add my thoughts here. First of all, thanks for your work! I've found this thread after noticing that Solargraph wouldn't know how to handle a goto definition click on has_many :users, where I'd expect it to open the User class. I'm not sure how much runtime magic is involved here but having this would be a big improvement.
Hi, any news on this?
Is there any dedicated branch for Rails where we could help you to implement it?
Solargraph's YARD support is at a point where some of the missing Rails intellisense can be filled with a small @!parse directive. I created a gist for it here: https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e
I'm looking for ways to improve it, including ways to make it easy to install and maintain. Any suggestions are welcome.
@castwide Using the gist above, it works well in many cases... thank you! However, in the 'activesupport' gem, there is a method blank? which is not getting picked up... is there a workaround? (.gem/ruby/2.5.3/gems/activesupport-5.2.2.1/lib/active_support/core_ext/object/blank.rb)
@mathieushopify It works in circumstances where a type can be inferred:
obj = Object.new
obj.b # <= suggests blank?
str = 'str'
str.b # <= suggests blank?
If those don't work, make sure you have the latest gem version (0.33.0 was released this morning) and run yard gems to make sure they're documented.
Completion won't work on on unknown types, which is unfortunately the status of most of the Rails API; for example, completion will suggest ApplicationRecord.find, but doesn't know what type find returns, so it won't make any suggestions for methods chained to it.
Makes sense, thanks for the prompt reply! :-)
@castwide Don't most types inherit from Object, though?
Although the lack of completions it can be a useful indicator that the type is in not inferred. "Some completions" is not always better than "no completions".
@dgutov Yeah, my personal preference is for undefined types to return no completions instead of assuming Object. It's less ambiguous about whether a type was detected.
If anyone finds it more useful to assume Object for untagged methods, we might be able to make it a configuration option.
Version 0.34.0 introduces some new features that should add some improvements to Rails support.
solargraph bundle from your Rails app's root directory.solargraph bundle makes sure that YARD documentation is installed for all your gems. Rails gems get parsed with RDoc first, then converted to YARD and saved in Solargraph's cache directory.Bundler.require and automatically adds gem dependencies to the map, so the @!parse require directives are no longer necessary.@!override in the gist applies overloaded methods with return types to ActiveRecord::FinderMethods#find.@!override directive might be a way to fix that, but I'm not sure if it'll be a long-term solution.solargraph clear && solargraph download-core to reset it.When you intend to fix this issue?
Using go-to-definition on a symbol with custom documentation should open the correct file, but it always goes to the first line. (Go-to-definition on other gems still works correctly.)
I think it should go to the correct line.
@castwide thanks for the update!
Great stuff! Thanks!
@castwide can you tell me that if that was an ordinary work or it have an issue??
@minkir014 I'm sorry, I don't know what you mean.
Gem 0.34.1 fixes some issues that occurred in certain bundler environments.
As I know about go to definition that it must go to a certain line that the class or any other thing is defined and you said
Using go-to-definition on a symbol with custom documentation should open the correct file, but it always goes to the first line. (Go-to-definition on other gems still works correctly.)
That means that some gems have problems with go to definition. So, when do you intend to fix this issue???
@minkir014 I don't know when it will be fixed because I don't even know what the root cause is. When the RdocToYard component generates an RDoc store, all the code objects have nil line numbers.
You could file an issue against RdocToYard gem. It maybe a problem with it.
Is there a way to manage models values with Solargraph?
E.g for the User model, to have autocompletion on user.id, user.created_at, etc...
@tvallois I'm working on a Rails convention that should be able to map model attributes from the database schema.
Right now the only other option is to document them yourself, e.g., with the @!attribute directive:
class User < ActiveRecord::Base
# @!attribute id
# @return [Integer]
# @!attribute name
# @return [String]
end
@castwide Hey, I was thinking of building a script that uses annotations built by annotate gem to add types to models. You said that you're working on something similar? Have you pushed any code towards that? I would like to help and start building it myself if you haven't :man_technologist:
# == Schema Information
#
# Table name: groups
#
# id :bigint(8) not null, primary key
# name :string
# created_at :datetime not null
# updated_at :datetime not null
# namespace_id :bigint(8) indexed
#
class Group < ApplicationRecord
# @!attribute id
# @return [Integer]
# @!attribute name
# @return [String]
# @!attribute created_at
# @return [Date]
# @!attribute updated_at
# @return [Date]
# @!attribute namespace_id
# @return [Integer]
...
end
@Zeko369 I don't have anything substantial. If you can build something, that would be awesome. I'm not sure how integration will work yet, but we can worry about those details after we have a working implementation.
@Zeko369 I would be happy to collaborate on this as well.
hi @castwide ,
I'm working on an implementation to generate yard documentation for models with annotate_models gem however when i have an attribute like:
# @!attribute generating
# @return [TrueClass]
# @return [FalseClass]
Solargraph only return TrueClass on the autocompletion. Is it a bug or normal behavior?
That's a known limitation. When you have multiple return tags, it should report all the types, but right now it only processes the first one. It works correctly if you add multiple types to a single tag, e.g., @return [TrueClass, FalseClass]. Support for multiple tags is on the roadmap. It's been a low priority, but it shouldn't be difficult.
In this case, you might prefer to use @return [Boolean] instead. It's not a real class, but YARD conveniently understands it.
2\. solargraph bundle
Sorry for this really newbie question, but where is located the rails.rbfile? I'm trying to diagnose why I always have the message
Starting the Solargraph language server
Thanks.
@romu70 Create a rails.rb file in the root of your project add do something like this https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e
Thanks @Zeko369 . Is this normal all the text in this file is commented out?
Having all the text commented is normal, yes. It uses YARD directives to augment the API maps without affecting real code.
The rails.rb file should be a temporary solution while we hammer out the details for proper Rails support. Eventually I'd like to have a plugin that automatically fills the gaps in the Rails API, similar to how the Solargraph core provides overrides for the Ruby stdlib and a "convention" for Gemfiles.
Ok thanks. I restarted my VSCode, but I'm still getting the permanent message "Starting the Solargraph language server"
Ok thanks. I restarted my VSCode, but I'm still getting the permanent message "Starting the Solargraph language server"
Try running solargraph stdio to start a server in your console, rather than vscode starting it for you. It should be easier to debug any issues it has starting that way.
@romu70 A few other things to help you troubleshoot:
solargraph scan -v to check for problems mapping your project (https://solargraph.org/guides/scanning-workspaces)Thanks for the help.
Error: Unable to read file (EntryNotFound (FileSystemError): Error: ENOENT: no such file or directory, open '/Users/romu/.vscode/extensions/rebornix.ruby-0.26.0/language-configuration-ruby.json')
solargraph scan -vprocessed 27727 pins in 16.6 seconds (approx).That error comes from the main Ruby extension. Their repo has an issue for it.
Since the scan seems okay, you might be encountering a bug in starting or connecting to the language server. If the problem persists, please start a new issue for it, and I'll try to help you continue troubleshooting.
I tried to get this file and put it into the rebornix folder shown in the error message.
Now, no more error.

And it seems to work correctly.

Even if, I've still the message in the status bar.

So I do confirm the problem was the language-configuration-ruby.json file was missing.
Is there a known way to gracefully handle has_many-like constructs?
I currently use:
# @!attribute members
# @return [ActiveRecord::Associations::CollectionProxy]
has_many :members,
through: :organizations_users,
source: :user
But really what would be awesome would be something like ActiveRecord::Associations::CollectionProxy<Users::User>, like an array. So that accesses to the elements have type information.
Seeing a bit of a strange behaviour here with Solargraph 0.39.8. I have a pretty standard application_record.rb file:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
When I try to find definition of ActiveRecord::Base, solargraph finds the active_record/base.rb file, but does not navigate to the ActiveRecord::Base class itself.
I'm also not seeing model magic methods, like where and so on, even though I have the tweaks from https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e under config/solargraph.rb.
Could these two things be related?
@immerrr
config directory (or, at least, the config/solargraph.rb file) included in your .solargraph.yml configuration?re: 2: solargraph.yml is the default one, that includes
include:
- "**/*.rb"
I suppose that means config/solargraph.rb should be included. Any way I can confirm that with more certainty?
I suppose that means config/solargraph.rb should be included. Any way I can confirm that with more certainty?
@immerrr Hmm, that's a good candidate for an enhancement. One workaround is to add a line like Class CanYouSeeMe; end to it and see if CanYouSeeMe is a completion suggestion in other files.
Have you tried running solargraph bundle from your project's root?
I commented this on the wrong issue, hopefully nobody gets spammed.
I've also been struggling getting the ActiveRecord to work well with solargraph. I'm not sure if I'm missing anything crucial. I've followed all the rails related help I could find.
I made a small generator using activerecord reflections, here is the gist
It just generates classes with yard / solargraph comments in them.
@Zeko369 @tvallois @qortex @castwide
@immerrr Update on the line number issue. There's a fix in the master branch that will be included in the next patch release.
The fix for line numbers is released in v0.39.9. You might need to run solargraph bundle --rebuild to regenerate cached documentation.
Just tried that out, failed with NoMethodError:
$ solargraph bundle --rebuild
Documenting rake 13.0.1
Documenting concurrent-ruby 1.1.6
Documenting aasm 4.12.3
Documenting i18n 1.8.2
Documenting minitest 5.10.3
Documenting thread_safe 0.3.6
Documenting tzinfo 1.2.7
Documenting activesupport 5.0.7.2
Caching custom documentation for activesupport 5.0.7.2
Traceback (most recent call last):
20: from /home/immerrr/.rvm/gems/ruby-2.5.8/bin/ruby_executable_hooks:24:in `<main>'
19: from /home/immerrr/.rvm/gems/ruby-2.5.8/bin/ruby_executable_hooks:24:in `eval'
18: from /home/immerrr/.rvm/gems/ruby-2.5.8/bin/solargraph:23:in `<main>'
17: from /home/immerrr/.rvm/gems/ruby-2.5.8/bin/solargraph:23:in `load'
16: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/bin/solargraph:5:in `<top (required)>'
15: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
14: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
13: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
12: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
11: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/shell.rb:193:in `bundle'
10: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/documentor.rb:26:in `document'
9: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/documentor.rb:26:in `each_pair'
8: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/documentor.rb:44:in `block in document'
7: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/yard_map/rdoc_to_yard.rb:17:in `run'
6: from /home/immerrr/.rvm/rubies/ruby-2.5.8/lib/ruby/2.5.0/tmpdir.rb:93:in `mktmpdir'
5: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/yard_map/rdoc_to_yard.rb:20:in `block in run'
4: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/yard_map/rdoc_to_yard.rb:20:in `chdir'
3: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/yard_map/rdoc_to_yard.rb:34:in `block (2 levels) in run'
2: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/yard_map/rdoc_to_yard.rb:34:in `each'
1: from /home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/yard_map/rdoc_to_yard.rb:41:in `block (3 levels) in run'
/home/immerrr/.rvm/gems/ruby-2.5.8/gems/solargraph-0.39.9/lib/solargraph/yard_map/rdoc_to_yard.rb:112:in `commentary': undefined method `parts' for #<String:0x0000000004d19cd8> (NoMethodError)
Just tried that out, failed with
NoMethodError:
That's weird. I'm sure I've never seen that attribute be a String before.
Fixed and released in v0.39.10.
Adding the gist seems to crash solargraph when running solargraph scan. It seems to be failing at the parse directive (removing it solves the issue), although it could be affecting any directive:
bundle exec solargraph scan
Traceback (most recent call last):
25: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/bin/ruby_executable_hooks:24:in `<main>'
24: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/bin/ruby_executable_hooks:24:in `eval'
23: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/bin/solargraph:23:in `<main>'
22: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/bin/solargraph:23:in `load'
21: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/bin/solargraph:5:in `<top (required)>'
20: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
19: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
18: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
17: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
16: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/shell.rb:171:in `scan'
15: from /Users/ferdaber.rvm/rubies/ruby-2.7.1/lib/ruby/2.7.0/benchmark.rb:293:in `measure'
14: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/shell.rb:172:in `block in scan'
13: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/api_map.rb:170:in `load'
12: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/api_map.rb:67:in `catalog'
11: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/api_map.rb:67:in `each'
10: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/api_map.rb:85:in `block in catalog'
9: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map.rb:156:in `map'
8: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:50:in `map'
7: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:27:in `map'
6: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:203:in `process_comment_directives'
5: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:203:in `each'
4: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:206:in `block in process_comment_directives'
3: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:69:in `process_comment'
2: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:69:in `each'
1: from /Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:72:in `block in process_comment'
/Users/ferdaber.rvm/gems/ruby-2.7.1@ferdaber/gems/solargraph-0.39.10/lib/solargraph/source_map/mapper.rb:158:in `process_directive': undefined method `strip' for nil:NilClass (NoMethodError)
I'm working on a fix. For now the workaround is to remove the comments above the @!parse directive. See also #329.
Fix released in v0.39.11.
Here is my latest gist for documenting AR attributes and relations on models, heavily influenced/plagiarized from other gists in this issue: https://gist.github.com/iftheshoefritz/7a195eb5676bb790cdbff91ab7d42f31. It generates files in config/yard, one per class, and my editor is now doing autocomplete nicely based on them.
Now I'm trying to look at how to go to definition. My editor takes me to the generated YARD files instead of to the original model source. I'm wondering if there is any way to get YARD to point readers to a location in a different file for the original source?
I'm guessing that solargraph bundle behaves similarly to this? Assuming it doesn't actually alter gem source but actually generates separate docs and has some record of the real source location. How does Solargraph do this?
Seeing a bit of a strange behaviour here with Solargraph 0.39.8. I have a pretty standard
application_record.rbfile:class ApplicationRecord < ActiveRecord::Base self.abstract_class = true end
I have the same generated application_record.rb and I find that with Strict typing I get this error:
/path/to/app/models/application_record.rb:2 - Unresolved call to abstract_class=
I do have the gist installed and confirmed working via the "CanYouSeeMe trick".
I tried adding a line include ActiveRecord::Inheritance to try to pull in the right definitions but it didn't work.
Is it expected that this fails? I'm a bit at a loss as to how to fix this.
@amake The line should be extend ActiveRecord::Inheritance::ClassMethods
I added it to the gist.
Thanks, that did it 馃憤
Hey, dunno if I'm missing something but I followed the instructions (installed the gist, ensured it works with the CanYouSeeMe trick), but even with a simple AR class I'm not seeing any finders or anything.
$ bundle exec solargraph scan -v | grep Employee
Employee (/Users/tyler/projects/movati/app/models/employee.rb 0)
Employee | ApplicationRecord (/Users/tyler/projects/movati/app/models/employee.rb 0)
How can I investigate further?
Hi, same here, everything is working very well, except that I don't have any inherited Rails methods.Ruby's methods and my project's methods are processed correctly. I followed all instructions previously given.
On all Rails methods (has_many, validates, ...) I get a unresolved call error (even if I require Rails gems in .solargraph.yml). I apparently have the same issue as @amake , but the gist update did not do the trick.
Putting @!attribute tags in models inherited from ActiveRecord does not fix the problem either. Are we supposed to write some other @parse tags or some sort in our classes? I don't know how to solve this unresolved call.
I forgot to mention that this behaviour appears on strict type checking mode only.
Thank you very much for your awesome work!
@tyler-boyd @Mate2xo What versions of Ruby and Rails are you using? It looks like the Rails gist doesn't work on certain combinations. For example, I got it to work as expected on Ruby 2.6.3 and Rails 6.0.3.2, but not on Ruby 2.3.0 and Rails 5.0.7.2.
@castwide For my current project, I am using Ruby 2.6.6 and Rails 6.0.3.3. I have actually noticed that I don't have autocompletion from Rails methods (e.g. no #find methods), but I get a few suggestions for a few class names.
E.g. I can type Active and then get the suggestion for ActiveRecord, I can then type :: (so to give ActiveRecord::), and then get suggestion forActiveRecord::Base; these suggestions come from the language server. All existing classes are not suggested though, and the only methods that are suggested are Ruby core methods (fromClass,ModuleandObject`)
So I have autocompletion for Ruby core definitions, and for everything I have defined in my project. I am using Vim with the Coc.nvim plugin, which actually uses VSCode's language server (if that's useful to know).
I will try to use it with Rails 5.2 and Ruby 2.5 on another project to see if I see any difference, and give you the feedback
I tried to get this file and put it into the rebornix folder shown in the error message.
Now, no more error.
And it seems to work correctly.
Even if, I've still the message in the status bar.
So I do confirm the problem was the
language-configuration-ruby.jsonfile was missing.
@romu70 How did you manage to get all of the activerecord methods?
-----------
Platform: x86_64-linux
Shell: /bin/zsh
Ruby Version: 2.7.1
RuboCop Version: 0.92.0
Rails Version: 6.0.3.3
Solargraph
---------------
vscode-solargraph: v0.21.1
Solargraph Version: 0.39.17
Core Documentation Version: 2.7.1
Core Cache Directory: ~/.solargraph/cache
Using Bundler: true
Project
Config: {"completion"=>true, "hover"=>true, "symbols"=>true, "definitions"=>true, "rename"=>true, "references"=>true, "autoformat"=>true, "diagnostics"=>true, "formatting"=>true, "folding"=>false, "logLevel"=>"warn", "enablePages"=>true, "viewsPath"=>"~/.vscode-insiders/extensions/castwide.solargraph-0.21.1/views", "transport"=>"socket", "externalServer"=>{"host"=>"localhost", "port"=>8708}, "commandPath"=>"$HOME/.rbenv/shims/solargraph", "useBundler"=>true, "bundlerPath"=>"bundle", "checkGemVersion"=>true}
@castwide I tried including the definitions.rb from https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e and also did bundle exec yard gems and bundle exec solargraph bundle --rebuild.
But still hover infos/defintions for certain callback methods etc are not shown in vscode, even though YARD docs exist. I'm wondering if it's an issue from my side or if it's a problem with the configuration.
Example of hover info I was referring to/expected hover info(this is taken from RubyMine):-

As you can see the before_action gets correct hover info in RubyMine. Not sure what their mechanism is. In vscode, we should get the same kinda info since I had added the following to the definitions.rb file in root of project. That is expectable, right?:-
# @!parse
# class ActionController::Base
# include ActionController::MimeResponds
# extend ActiveSupport::Callbacks::ClassMethods
# extend AbstractController::Callbacks::ClassMethods #--------> This should provide the info for before_action, right?
# end
Currently in vscode no hover info/go to definition is available for before_action and other callback methods etc.
Current bundle exec solargraph scan -v reports an error which I don't know if it's the reason for not showing hover info/definitions(the errors have been cut short since it's very long):-
RubyVM::AbstractSyntaxTree
RubyVM::AbstractSyntaxTree::Node
RubyVM::AbstractSyntaxTree::Node | Object
Errno::ENOTEMPTY
Errno::ENOTEMPTY | SystemCallError
Errno::ENOTNAM
Errno::ENOTNAM | SystemCallError
.
.
.
Errno::ENOTCONN
Errno::ENOTCONN | SystemCallError
Errno::ENOTDIR
Errno::ENOTDIR | SystemCallError
Scanned ~/granite (20340 pins) in 8.750855500999933 seconds.
My .solargraph.yml:-
---
include:
- "**/*.rb"
- "config/model_definitions/task.rb"
- "definitions.rb"
exclude:
- spec/**/*
- test/**/*
- vendor/**/*
- ".bundle/**/*"
require:
- actioncontroller
- actioncable
- actionmailer
- actionpack
- actionview
- activejob
- activemodel
- activerecord
- activestorage
- activesupport
domains: []
reporters:
- rubocop
- require_not_found
- typecheck
require_paths:
- "config/model_definitions"
plugins: []
max_files: 10000
Solargraph in Gemfile:-
group :development do
gem 'rubocop', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-performance', require: false
gem 'reek', require: false
gem 'solargraph', require: false
gem 'yard', require: false
end
Running the local bundle exec yard server --gems within the project, shows me the docs related to all gems and showsAbstractController::Callbacks::ClassMethods for actionpack which we included in definitions.rb. So if yard has the docs related to a particular method, then wouldn't solargraph be able to use that directly?

class TasksController < ApplicationController
before_action :load_task, only: %i[show edit update destroy]
# @!parse extend ActionController::Instrumentation
def new
p method(:render).owner.ancestors
render # ------------------------------------------> I don't get any definitions for public method render from ActionController::Instrumentation in vscode even when I had added the YARD comment above
end

As I have created setup for my project and included the Gist, latest version of solargraph does not provide any ActiveRecord class methods for AR classes. Just generic list of Object methods. not sure if I am doing everything right but I have completed steps in a comment above.

seems to be the same case as @Mate2xo
upon further inspection scan does not include any methods from rails gems for some reason(with or without defintions.rb).
rails 6.0.3.3
ruby 2.6.5
solargraph 0.39.17
Having the same issue, no AR methods. Using rails.rb definitions.
I did have success with @iftheshoefritz script for methods: https://gist.github.com/iftheshoefritz/7a195eb5676bb790cdbff91ab7d42f31
But no class level methods.
Rails 6.0.3.4
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin19]
solargraph (0.39.17)
Having done some digging I can verify that methods do appear in v0.38.6, did a bit more skip testing:
v0.39.0 fails to bundle, v0.39.5 bundle success, no methods appear,v0.39.10 bundle success, fails to start server,v0.39.15 bundle success, no methods appearCheers
@RobertLowe I'm wondering if it's a compatibility issue with the Ruby version. Can you please check if you get proper intellisense and auto-completions for solargraph v0.38.6 which worked for you and somewhat latest ruby version say 2.7.2 or 2.7.1?
Thanks
Also, if possible, let me know whether your solargraph was installed via Gemfile or globally. I always handled both yard and solargraph from my Gemfile.
@yedhink locally bundle install'd gems no globally install ones:
v0.38.6 + ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19], bundle success, methods appear
v0.39.17 + ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19], bundle success, no methods appear
Cheers
Another thing:
# extend ActiveRecord::Persistence::ClassMethods
Should be added to class ActiveRecord::Base in https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e
@RobertLowe How do I run that gists you have posted https://gist.github.com/iftheshoefritz/7a195eb5676bb790cdbff91ab7d42f31
@guledali From the comments in the script:-
# run the script as a rails runner:
# bundle exec rails r ./bin/generate_solar_models.rb
Make sure you customise the paths appropriately to suit your project, within the script. Ultimately, after running that script, we get instance methods and variables associated with a particular model/table i believe. And I also think, we might've to run it often, when adding new attributes to the table.
[Edit] I think using it as rake task can workout.
require 'fileutils'
namespace :solargraph do
task update_model_definitions: :environment do
if Rails.env.development?
Rails.application.eager_load! unless Rails.application.config.cache_classes
Zeitwerk::Loader.eager_load_all if defined?(Zeitwerk)
# model_definitions should be replaced whatever dir name you want in config dir
ApplicationRecord.descendants.each do |model|
def_file = Rails.root.join('config', 'model_definitions', "#{model.name.underscore}.rb")
FileUtils.mkdir_p File.dirname(def_file)
File.open(def_file, 'w') do |file|
file << "class #{model.name}\n"
klass = model.name.constantize
klass.attribute_names.each do |name|
file << "# @!attribute [rw] #{name}\n"
file << "# @return [#{ruby_type[klass.type_for_attribute(name).type]}]\n"
end
file << "end\n"
end
end
end
end
task generate: :environment do
# Add the folder you choose in your config/application.rb
# example:
# config.autoload_paths << Rails.root.join('app/solargraph')
gen_directory = Rails.root.join('config', 'model_definitions')
# run the script as a rails runner:
# jundle exec rails r ./bin/generate_solar_models.rb
# if you wanted to choose specific models to generate for
# models = [User]
Rails.application.eager_load!
models = ApplicationRecord.descendants
puts("generating for #{models.count} models")
models.each do |model|
puts "processing #{model.name}."
columns = model.columns.map do |col|
type = type_translation[col.type]
<<~TXT
# @!attribute #{col.name}
# @return [#{type}]
TXT
end
reflections = model.reflections.map do |key, reflection|
type = reflection_comment(reflection)
puts "KEY: #{key} TYPE: #{type}"
next if type.nil?
<<~TXT
# @!attribute #{key}
# @return #{type}
TXT
end
generated_attributes = <<~TXT
class #{model.name}
#{reflections.join("\n")}
#{columns.join("\n")}
end
TXT
path = gen_directory.join("#{model.model_name.singular}.rb")
File.write(path, generated_attributes)
puts("written : #{path}")
end
end
def type_translation
{
array: 'Array',
boolean: 'Boolean',
date: 'Date',
datetime: 'DateTime',
decimal: 'Decimal',
float: 'Float',
integer: 'Integer',
string: 'String',
text: 'String',
time: 'Time'
}
end
def class_for(name)
name = name.to_s
found = ApplicationRecord.descendants.detect do |model|
model.model_name.plural == name || model.model_name.singular == name
end
found&.first&.model_name&.name
end
def reflection_type(reflection)
puts "Reflecting with #{reflection}"
case reflection
when ActiveRecord::Reflection::HasManyReflection
:many
when ActiveRecord::Reflection::HasAndBelongsToManyReflection
:many
when ActiveRecord::Reflection::HasOneReflection
:one
when ActiveRecord::Reflection::BelongsToReflection
:one
when ActiveRecord::Reflection::ThroughReflection
reflection_type(reflection.through_reflection)
else
puts("# cannot infer association for #{reflection.name} -> #{reflection.class}")
nil
end
end
def reflection_class_name(reflection)
case reflection
when ActiveRecord::Reflection::HasManyReflection
class_name =
reflection.options[:class_name].presence || class_for(reflection.name)
class_name
when ActiveRecord::Reflection::ThroughReflection
class_name =
reflection.options[:class_name].presence || class_for(reflection.name)
class_name
when ActiveRecord::Reflection::HasAndBelongsToManyReflection
class_name =
reflection.options[:class_name].presence || class_for(reflection.name)
class_name
when ActiveRecord::Reflection::HasOneReflection
reflection.name.to_s.capitalize
when ActiveRecord::Reflection::BelongsToReflection
reflection.name.to_s.capitalize
else
puts("# cannot infer association for #{reflection.name} -> #{reflection.class}")
nil
end
end
def reflection_comment(reflection)
case reflection_type(reflection)
when :one
"[#{reflection_class_name(reflection)}]"
when :many
"[Array<#{reflection_class_name(reflection)}>]"
end
end
end
def ruby_type
{
array: 'Array',
boolean: 'Boolean',
date: 'Date',
datetime: 'DateTime',
decimal: 'Decimal',
float: 'Float',
integer: 'Integer',
string: 'String',
text: 'String',
time: 'Time'
}
end
@yedhink Where do I put the file? In the root and what do you mean by this,
_"Make sure you customise the paths appropriately to suit your project, within the script"_
I have placed the script in lib/generate_solar_models.rb and I have not modified the script above

Running the command gives bundle exec rails r lib/generate_solar_models.rb

Gives this result,

@yedhink The question now is have I missed some?
You forgot to add
require 'rake'
at the top of the file
@RobertLowe I can confirm that intellisense works pretty good with v0.38.6 as you suggested. Thanks again. Until a further notice from the developer about the issue, I will stick with this version.
@guledali just make it a rake task and run bundle exec rake solargraph:update_model_definitions
Put in the lib/tasks/generate_solar_models.rake adding .rake at the end and the running the
bundle exec rake solargraph:update_model_definitions
@yedhink you're welcome @guledali yes, make it rake task just like that
cheers all
Hi, I still can't up and run completion for AR attributes, i run the above script and i have this structure.
before:

after:

The problem is that you have to configure the rails.rb
# The following comments fill some of the gaps in Solargraph's understanding of
# Rails apps. Since they're all in YARD, they get mapped in Solargraph but
# ignored at runtime.
#
# You can put this file anywhere in the project, as long as it gets included in
# the workspace maps. It's recommended that you keep it in a standalone file
# instead of pasting it into an existing one.
#
# @!parse
# class ActionController::Base
# include ActionController::MimeResponds
# extend ActiveSupport::Callbacks::ClassMethods
# extend AbstractController::Callbacks::ClassMethods
# end
# class ActiveRecord::Base
# extend ActiveRecord::QueryMethods
# extend ActiveRecord::FinderMethods
# extend ActiveRecord::Associations::ClassMethods
# extend ActiveRecord::Inheritance::ClassMethods
# include ActiveRecord::Persistence
# end
# @!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>]
This does not cover rails at all, so many autocompletion missing both in the controller and model, obviously you could extend that file but who has the time for that. Alternative there is free version for rubymine https://www.jetbrains.com/ruby/nextversion/
@amirhosseinak20 looks like you are expecting your editor to give you completion about AR attributes on the class. They are instance level attributes, so you need to try completion on an instance. What happens if you type User.new.? Do you see the attributes then?
@amirhosseinak20 looks like you are expecting your editor to give you completion about AR attributes on the class. They are instance level attributes, so you need to try completion on an instance. What happens if you type
User.new.? Do you see the attributes then?
When i type sth like "User.fi" it doesn't show any completion (i expect to show first), but when i type "a = User.new; a.em" it shows email.
Help is ~on the way~ in progress. I've started https://github.com/iftheshoefritz/solargraph_rails which is a SG plugin that parses Annotate comments to give magical IDE help on ActiveRecord attributes. It does this without generating any local files that confuse go-to-definition. Associations will come later, but those are IMO an easier problem to solve.
It relies on an unreleased feature of Solargraph (Conventions), but if you're willing to build things from source you can use it now. I've tested it on a Rails API that is a few years old and it does what I need. The API is far from the biggest, dirtiest Rails app that I work on, so there are probably lots more issues to find, and plenty of refactoring and performance stuff to think about.
(shoutout to @castwide for implementing Conventions in master, do we have any timelines on when v.0.40 will be released?)
Help is ~on the way~ in progress. I've started [iftheshoefritz/solargraph_rails](https://github.com
on here be dragons where does one find solargraph 40.1 ? reading shoutout, want to forgo unnecessary yak shaving.
Suppose I can push version to 40.1 by hand. Not sure if that what you have done.
on here be dragons where does one find solargraph 40.1 ? reading shoutout, want to forgo unnecessary yak shaving.
You have to build solargraph from source, and set the version number to that (which I chose arbitrarily, Castwide actually said the next version would be v0.40.0).
on here be dragons where does one find solargraph 40.1 ? reading shoutout, want to forgo unnecessary yak shaving.
You have to build solargraph from source, and set the version number to that (which I chose arbitrarily, Castwide actually said the next version would be v0.40.0).
Also probably better find a different name, there is already solargraph-rails, which I have installed instead of this one on the first go.
Also probably better find a different name, there is already solargraph-rails
馃う and I see it is owned by Castwide himself
@iftheshoefritz The current solargraph-rails gem is a legacy Rails app that I've been meaning to deprecate. I'm on board with publishing your plugin under that name to stay consistent with existing plugin conventions.
(shoutout to @castwide for implementing Conventions in master, do we have any timelines on when v.0.40 will be released?)
I delayed it while I was researching a wart in how convention changes get applied to api maps. Then I got temporarily sidetracked with other work. 馃う I'll try to have an update and an ETA before the end of the week.
@castwide Thanks! Is the convention solargraph-rails or solargraph_rails (minus or underscore)?
@iftheshoefritz dash imo
Yep, solargraph-rails. Current examples include solargraph-reek and solargraph-standardrb.
With the release of gem v0.40.0, I think we're about ready to develop a proper Rails plugin for Solargraph. My proposal is to combine the Rails supplemental file with iftheshoefritz's model annotation. This would take a lot of the maintenance out of users' hands while still allowing them to apply their own supplemental file if necessary.
@iftheshoefritz, any thoughts on this? As I said earlier, I'd be happy to yank the legacy solargraph-rails gem so we can repurpose the name. That just leaves the question of how to coordinate collaboration and maintenance.
@castwide that sounds good! If you could remove solargraph-rails, I'll rename my project and upload version 0.1.1pre or some such to rubygems.org
@iftheshoefritz is your RubyGems username also iftheshoefritz? I figure the safest way to switch is for me to make you an owner, so it doesn't get squatted mid-transfer. You can also email me so we can coordinate more directly (my email is in my profile).
@castwide yes, I am iftheshoefritz there too :)
Most helpful comment
There are a couple of things you can try.
Make sure you have gem documentation installed by running
yard gems.Add a .solargraph.yml file to the app's root directory (you can generate a default one by running
solargraph config) and make the following change to therequiresection:That should get you closer, but it's still far from perfect. Improving Rails support has been on the roadmap for a while. The amount of runtime magic involved makes it challenging, but I have some updates in the works that should help.