RubyMine: More Distractions (Part 2)
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.
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.
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]
.
RubyMine is convinced that looking up any key from the Parameters
object will return another Parameters
object.
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:
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.
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.
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.
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.
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.