solargraph icon indicating copy to clipboard operation
solargraph copied to clipboard

Rails support

Open philevans opened this issue 7 years ago • 131 comments

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.

philevans avatar Sep 17 '18 12:09 philevans

There are a couple of things you can try.

  1. Make sure you have gem documentation installed by running yard gems.

  2. 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.

castwide avatar Sep 17 '18 18:09 castwide

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.

andersennl avatar Oct 16 '18 08:10 andersennl

Hi, any news on this?

Is there any dedicated branch for Rails where we could help you to implement it?

tvallois avatar Jun 13 '19 09:06 tvallois

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 avatar Jun 14 '19 15:06 castwide

@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 avatar Jun 18 '19 18:06 mathieushopify

@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.

castwide avatar Jun 18 '19 19:06 castwide

Makes sense, thanks for the prompt reply! :-)

mathieushopify avatar Jun 18 '19 19:06 mathieushopify

@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 avatar Jun 18 '19 21:06 dgutov

@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.

castwide avatar Jun 18 '19 22:06 castwide

Version 0.34.0 introduces some new features that should add some improvements to Rails support.

Quick Start

  1. Install the latest Solargraph gem.
  2. Run solargraph bundle from your Rails app's root directory.
  3. Add the most recent version of this file: https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e

How It Works

  • 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.
  • The YardMap detects that the code calls Bundler.require and automatically adds gem dependencies to the map, so the @!parse require directives are no longer necessary.
  • The gist file adds explicit references to a few more modules that Rails automagically includes and extends.
  • The @!override in the gist applies overloaded methods with return types to ActiveRecord::FinderMethods#find.

Known Issues

  • Although this process fills in a lot more methods, practically none of them have documented return types. The @!override directive might be a way to fix that, but I'm not sure if it'll be a long-term solution.
  • 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.)
  • The RDoc-to-YARD conversion is necessary so Rails magic methods documented in RDoc will be visible in Solargraph. It might be a good idea to implement this feature as a YARD plugin.
  • If the custom documentation gives you any trouble, you can run solargraph clear && solargraph download-core to reset it.
  • There are a lot more includes and extends that could be added to the gist. Any help is appreciated.

castwide avatar Jun 25 '19 09:06 castwide

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.

minkir014 avatar Jun 25 '19 11:06 minkir014

@castwide thanks for the update!

mathieushopify avatar Jun 25 '19 11:06 mathieushopify

Great stuff! Thanks!

dirksierd avatar Jun 25 '19 19:06 dirksierd

@castwide can you tell me that if that was an ordinary work or it have an issue??

minkir014 avatar Jun 27 '19 00:06 minkir014

@minkir014 I'm sorry, I don't know what you mean.

castwide avatar Jun 27 '19 00:06 castwide

Gem 0.34.1 fixes some issues that occurred in certain bundler environments.

castwide avatar Jun 27 '19 02:06 castwide

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 avatar Jun 28 '19 21:06 minkir014

@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.

castwide avatar Jun 29 '19 01:06 castwide

You could file an issue against RdocToYard gem. It maybe a problem with it.

minkir014 avatar Jun 29 '19 12:06 minkir014

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 avatar Sep 05 '19 14:09 tvallois

@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 avatar Sep 07 '19 12:09 castwide

@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 avatar Sep 24 '19 09:09 Zeko369

@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.

castwide avatar Sep 25 '19 20:09 castwide

@Zeko369 I would be happy to collaborate on this as well.

Samsinite avatar Oct 02 '19 17:10 Samsinite

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?

tvallois avatar Jan 15 '20 10:01 tvallois

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.

castwide avatar Jan 15 '20 16:01 castwide

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 avatar Feb 04 '20 20:02 romu70

@romu70 Create a rails.rb file in the root of your project add do something like this https://gist.github.com/castwide/28b349566a223dfb439a337aea29713e

Zeko369 avatar Feb 04 '20 21:02 Zeko369

Thanks @Zeko369 . Is this normal all the text in this file is commented out?

romu70 avatar Feb 05 '20 20:02 romu70

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.

castwide avatar Feb 05 '20 20:02 castwide