RubyMine: More Distractions (Part 2)
By: Andrew Roberts
Tags: Rubymine, Rails, Jetbrains, Ruby on Rails, Ruby

Do check out Part 1 if you’re not familiar with my concerns regarding RubyMine. As mentioned, I’ve got dozens of niggles that bug me, so here are five more things that I tend to spot on a semi-regular basis whilst I’m working on my Rails projects.

Models with JSON datatype

The typical databases that Rails developers are likely to use, MySQL, PostgreSQL, SQLite, all support the JSON datatype. And Rails will also support the JSON type as a first-class database within its database migrations DSL.

Unfortunately RubyMine doesn’t recognise them. The first obvious signal that something is amiss is the migration itself. It underlines the json datatype because it can’t find a reference to this type.

An example migration containing a column with JSON datatype. RubyMine highlights the json type because it doesn’t recognise it.

RubyMine will usually offer the model’s attributes in the suggestions box. The attribute with the JSON type (named metadata ) is not there though.

And as mentioned in part 1, despite RubyMine believing the metadata attribute does not exist, it won’t flag as an error because… there exists within the imported gems a class with the method name metadata — the fact that it’s not at all accessible is overlooked.

RubyMine does not think that Comment modal has an attribute called `metadata`. However, it won’t give a warning, because there exists a method elsewhere with the name `metadata`!

Rails controller params

ActionController provides a special params method that returns a Parameters object (that is basically fancy Hash). All parameters, whether GET or POST are accessible via this object, plus Rails sticks a few extra things in there too, in particular, dynamic segment that are passed via the URL. E.g., for the below routes, the value for the user_id in the URL /users/123/profile/new could be accessed via params[:user_id] .

Sample routes for users resources with profile sub-resource.

RubyMine is convinced that looking up any key from the Parameters object will return another Parameters object.

Hovering over the variable shows that RubyMine thinks this value will be an instance of Parameters.

This is not the case. It may be a Parameters object if the value also needs to hold a Hash-like structure.

params = ActionController::Parameters.new(person: { name: "Francesco" }, id: 1) params[:person] # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false> params[:id].class # => Integer

This is obviously part of the widespread type inference deficiency that RubyMine suffers from as documented in part 1. It’s annoying for me because I often have method signatures that have a defined, expected type, e.g., an integer, but if I pass params[:id] to that method then RubyMine flags it with a warning, effectively saying that I shouldn’t be passing a Parameters object to an argument that expects an Integer . No sh*t!

On a slightly different note… It’s incredibly common to be dealing with params for CRUD operations. Wouldn’t it be nice if RubyMine could assist with params? Two ways come to mind. Firstly, RubyMine could parse routes.rb file to offer some suggestions for the dynamic segments? That is, if I start typing params[: then it would offer :user_id as the top suggestion.

Secondly, the other common thing to do is permit which params are allowed to be passed to ActiveRecord for use in creating/updating records.

So before passing incoming params to your AR object you accept the values that can be used.

params.require(:person).permit(:name)

The require method will typically accept a value that corresponds to a Model, and given that Rails does have all the column names defined in its schema reference, then it would be lovely for non-trivial cases where a modal may have dozens of attributes to have the permit method with useful suggestions.

Spellcheck

Spellcheck is useful. I do expect to have to regularly add words not in the typical spell check dictionary. However, it’s quite common to get a few false positives. One place which seems particularly tricky is URIs. For example, in one project I’ve got a single stylesheet import coming from a CDN, spanning over two lines.

If you look closely there are a bunch of squiggly underlines. Those are what RubyMine deems as spelling errors. Here’s the full list:

The Problems panel showing four typos within the CSS import, three of which part of the sha256 hash.

Good to know that TMnZhxCq is valid but Fxjqi is being caught!

Based on observation, what is going on here is RubyMine doesn’t check words with three characters or less. That seems reasonable. What is interesting though is that a word boundary is not necessarily whitespace or punctuation. An uppercase letter is also a boundary, just like it is with CamelCase. Hence according to RubyMine:

uid # OK

uidu # Typo

uidU # OK

uidUi # OK

uidUid # OK

The issue here is that typos are highlighted throughout the code, in the Problem Highlights at the top-right of every code window, and in the Problems panel. It is annoying having to address flagged issues that are not issues. The only way to make typo warnings go away is to add them to the project dictionary. Please add an ignore option, because Tvjfe is genuinely not a word!

Even when there’s a genuine typo spotted, it would be nice to have a sensible suggestion presented within the quick-fix panel rather than a sub-menu item.

Suggestions for the replacement word is not initially present. Have to click through the top “Typo: Change to…” menu item.

Note: I’ve recently seen a blog that mentions some improvements of the spell-checker. They must have read my mind! I think they will soon include the list of typo suggestions in the quick-fix panel without that extra click. At last!

Documentation pop-up/window

Hovering over a class or method, or pressing the F1 key will open up a documentation pop-up (or there’s a dedicated Documentation window that you can keep open). Very handy. Ruby, and Rails, have lots of documentation within the code itself and that can be presented by RubyMine if available. The problem I encounter is that it seems to struggle finding the information I’m after, especially in Rails projects where the same method name is used in multiple places.

The redirect_to method is an extremely flexible method of ActionController (that resides in ActionController::Redirecting module) that accepts many different ways to expressing the page one wishes to redirect to. Therefore it’s not uncommon to wish to consult the docs every now and again. RubyMine will instead show you the ActionController::Instrumentation.redirect_to() . Is it wrong? Probably not. I think, although haven’t delved, that ActionController::Instrumentation.redirect_to() is in fact being first, because it’s being used as a wrapper to log the controller actions. But the method that any user will actually care about, is ActionController::Redirecting.redirect_to . As a result it’s the same with render , send_file and send_data .

Another key area is ActiveRecord. Methods like find , find_by and where are commonly used and sometimes one needs to double-check how to use them (particularly what they return when nothing matches). RubyMine won’t offer you anything of interest other than a link to the ActiveRecord module on RubyDoc and from there you’ll have to go browsing for the right module and then scroll to the method.

And it’s the same with .where() .

The documentation viewer is a top-level feature according to Jetbrains, and is near the top of the list of highlighted features on the RubyMine product page. But it’s luck of the draw as to whether you’ll hit a good match or not.

The RubyMine promo page has the documentation viewer as the fourth item in the list (bottom-right)

Windows/tabs

It really gets on my nerves just how hard it is to move editor tabs around. On Sublime Text or Visual Studio Code, tabs just glide from one split pane to another. In RubyMine the tabs do not want to detach from their current pane.

Trying to drag a tab from the left pane to the right. It will not leave it’s current pane in this manner.

It is possible to drag, but first you must drag it down, and after a noticeable lag it’ll detach, and then it can be dragged across.

Drag the tab down first, and then across. I appreciate it’s not hard, but my intuition is to do the former action of dragging right only.

Note: I’ve recently seen in an announcement that the soon-to-be-released 2020.3 version has editor tab improvements. I have no idea if it resolves this particular snag. Fingers crossed.

In conclusion

I just wish everything was a bit more refined. When you use Visual Studio Code the thing is damn slick.

All the pieces are there in RubyMine. I’ve said it before: more common-sense please.