Double colon in class name and RubyMine complaints about short name - ruby-on-rails

I have the following autogenerated controller in
conrollers/v2/base_controller.rb.
class V2::BaseController < ApplicationController
end
It was generated by Versionist gem. I am trying to make a controller inherited from V2::BaseController. I wrote
class V2::MainController < V2::BaseController
def index
render :text => 'abcde'
end
end
It works fine and I can see my text rendered in browser. However, RubyMine IDE complains that the class name V2 in V2::MainController is too short and I should rename the class.
I am confused because I thought that V2:: means that we define a new class inside V2 module. If I am wrong, then why does RubyMine ignore the same problem with BaseController?
UPD: RubyMine complaint

RubyMine uses reek for code smell detection.
Warning it's giving you is called Uncommunicative Module Name.
Uncommunicative Module Name checks for:
1-character names
any name ending with a number
In your case warning was caused with 2 in V2. Even for Version2 it would be the same.
But it's actually only a recommendation. Ruby works fine with this code.

Nah, it's just a notice for you as a programmer. Short variable names are usually cryptic and less intention-revealing, so it's a nice check to have, but is definitely not a required one.
I think that V2 is perfectly fine for your case, but if you're still concerned, just rename it to Version2 to make Rubymine happy. I don't know if it will be still compatible with the gem you use. it seems Rubymine doesn't like any variable with a number on the end.
But why does IDE show the notice only for MainController?
I can think about 2 options here:
It's some glitch in RubyMine indexing. Or maybe it was made this way not to spam your file tree with red underlines (one is actually enough for you to notice that). Try restarting the IDE and see if it goes away.
RubyMine can't find definition of V2 module, because V2 in class V2::MainController is a reference to defined module somewhere, and not its definition. Solution: create the empty module and see if your warning goes away.
app/controllers/v2.rb
module V2
end

Related

How to delete a helpers file in Rails 5?

I'm new to Rails, and after using rails g controller Users to generate a users controller, I decided to remove (i.e., rm) the generated helper in app/helpers/users.rb, because I realized I didn't need it. It seems ugly to keep a bunch of empty files around to me. This broke my app. When I try to visit any page in my, or run a test, I get this error: Couldn't find UsersHelper, expected it to be defined in helpers/users_helper.rb.
I fixed it by manually re-creating that file, but how do I get rid of it? Is that just not supported?
Edits based on questions people asked
The helper does not appear to be referenced explicitly anywhere, grep -Ri UsersHelper . only returns results for the module itself and a bootsnap cache file. The same command with :helper 'user' or 'helpers/users' returns nothing.
If Rails is telling you that it can't find UsersHelper then it means that the module is called somewhere else in the project. When the page shows you the couldn't find message, it should also indicate the offending file where UsersHelper is being included (same with the test output). If you remove this reference, you should have no problem removing the module (or directory).
I sort of figured out the issue, but I still don't understand it.
I am using some url helper functions: user_url(:id) and new_user_url, and these apparently require the helpers to exist even though they are not explicitly defined there. If anyone can explain in more depth what's going on, I'd appreciate it.

Unable to initialize class in Rails App

Directory:
Prototype
-app
-assets
-controllers
---welcome_controller.rb
domainobjects
---SimilarJob.rb
Utilities
--API.rb
Controller Code
require_relative '../domainobjects/SimilarJob'
class WelcomeController < ApplicationController
def index
foo = API.new('DEVKEY')
res = foo.RetrieveFacts("Test", "Me")
#newResult = SimilarJob.new("test") <-- Failing Line!!!
render :text => res["Response"]["IsInternationalResponse"]
end
end
Object Code
class SimilarJob
end
I stripped out some things, but the API class exists in a separate directory, "Utilities", and for some reason I don't even have to reference it using the "requires_relative" keyword. It's a wrapper class that includes HTTParty and makes a successful GET request to my external API every time. Can someone explain why I seemingly don't have to reference it anywhere?
Alternatively, attempting to initialize the SimilarJob class fails each time. The error is:
uninitialized constant WelcomeController::SimilarJob
From what I researched here and on the web, this means I'm not referencing the file correctly. To test this out, I tried naming it incorrectly in the "requires_relative" statement and the framework informs me that the requested file could not be loaded. So it seems like Rails is finding my class, it just won't initialize it for some reason.
The most maddening part is that I'll make a few small changes to SimilarJob, restart my server, and it'll work all of a sudden. If I stop and start the server again, it's back to the error I pasted below.
This is my first time really digging in something other than .NET MVC or KnockoutJS..would you guys mind pointing out the error of my ways?
EDIT: I used the generate command for this controller, so all views and routes work appropriately. In fact, if I comment out the problematic line, the property I'm referencing on the last line in my JSON response renders to the file just fine.
EDIT v2: Strangely enough..changing my class name to Jobs (one word) is getting rid of this error. This comes off as bizarre! Can anyone confirm that this is my issue?
Names matter, and you've named your file wrong. SimilarJob.rb needs to be similar_job.rb.
Similarly, your API file should be called api.rb, and the class it defines should be called Api. This stuff is important, as you've deviated badly from Rails convention, and are suffering for it.

Ruby - :: in class name

I'm working with some legacy RoR code, which has four related classes, each defined in its own file. All of these classes are parser classes, and live in app/models/parsers. Each file name ends with _parser.rb.
Here's an example class def line from file adf_parser.rb:
class Parsers::AdfParser
I'm lost as to what the Parsers:: part of that is doing.
There's no explicit module called Parsers defined anywhere that I can find.
I don't see any documentation about implicitly creating modules just by adding module specifications to class names.
The only external dependency is "require 'csv'".
There are include statements within the class def, but I don't think they have anything that would explain the class name.
I created a new RoR test project and put stubs of these files in a parallel directory, and they won't run from the command line due to a
name error.
I don't see any examples online of classes named in this way.
I'm sure this isn't rocket surgery, but I've lost most of my morning trying to figure this out, and I'd love it if someone could just tell me what's going on with it.
Update: It sounds like this is just a bit of Rails magic, based on the subdirectory name. I think the reason that I got an error in my test app is that I just ran the files through the ruby interpreter, rather than invoking them with Rails in some way.
class Parsers::AdfParser is in practice equivalent to:
module Parsers
class AdfParser
For this to work properly, and the file to be autoloaded its location should be parsers/adf_parser.rb, whether under app/models or lib. Basically the file path needs to mimic the class hierarchy.
It's in the parsers sub-directory of modules; Rails namespaces for you by convention.

Using Ruby alias to extend a Gem

This is more a theoretical question, but I am curious anyway. I am a ruby / ruby on rails newbie (but with a lot of ancient experience in other languages / frameworks) so this is mainly a curious / learning question. Thanks in advance for any help!
I thought I could do a quick extension to a ruby gem using alias as follows:
module InstallMyExtension
def self.included(base)
base.class_eval {
alias :some_method_in_gem_without_my_extension :some_method_in_gem
alias :some_method_in_gem :some_method_in_gem_with_my_extension
}
end
def some_method_in_gem_with_my_extension
debugger
# ... do fun stuff here
some_method_in_gem_without_my_extension
end
end
Then in some initialization file I do:
Foo::SomeControllerInFoo.send :include, InstallMyExtension
I learned this technique in the Radiant CMS where its used all over the place to extend base behavior. I understand this technique is now disapproved of, but it seemed like a quick way to just try some ideas out, before forking a branch on the gem, etc, etc
First off is there a better way in Rails 3 to do a quick hack extension like this (which might be useful just to test a theory, before forking the gems etc???)
Second off, its not working, and there are multiple things I don't understand
Then let me explain the weirdness I am seeing:
Even if I do do the the "include" as shown above, when I go into the console I see some really weird behavior, that I don't understand:
1) I type Foo::SomeControllerInFoo i get back Foo::SomeControllerInFoo as I would expect. HOWEVER if run the same exact expression a second time, Foo::SomeControllerInFoo comes back undefined!
2) Just to play around I did foo = Foo::SomeControllerInFoo, and then I can do foo.send, foo.methods, whatever I like, but only if I save the copy of the class in foo! What's with that?
3) If I now do foo.send :include, MyExtension the behavior within the debug console is as expected (i.e. the original class contained in the gem now has my behavior added to it.) HOWEVER running the same code during initialization has no effect. Nothing breaks, but the controller is not extended.
Weird that it doesn't work, I just tried again to be sure and that does the trick (put this code in a file within config/initializers).
I always use a shortcut:
alias_method_chain :some_method_in_gem, :my_extension
instead of the two aliases lines, but it's exactly the same.
You could overwrite some methods much more easily using class_eval directly. Again in an initializer:
Foo::SomeControllerInFoo.class_eval do
def some_method_in_gem
#your redefinition
end
end
Sorry but no added value for your other questions: seems just really weird and buggy.
Just to be sure, when you want to run the method defined in your controller, do:
c = Foo::SomeControllerInFoo.new
c.method_name

How to fix / debug 'expected x.rb to define X.rb' in Rails

I have seen this problem arise in many different circumstances and would like to get the best practices for fixing / debugging it on StackOverflow.
To use a real world example this occurred to me this morning:
expected announcement.rb to define Announcement
The class worked fine in development, testing and from a production console, but failed from in a production Mongrel. Here's the class:
class Announcement < ActiveRecord::Base
has_attachment :content_type => 'audio/mp3', :storage => :s3
end
The issue I would like addressed in the answers is not so much solving this specific problem, but how to properly debug to get Rails to give you a meaningful error as expected x.rb to define X.rb' is often a red herring...
Edit (3 great responses so far, each w/ a partial solution)
Debugging:
From Joe Van Dyk: Try accessing the model via a console on the environment / instance that is causing the error (in the case above: script/console production then type in 'Announcement'.
From Otto: Try setting a minimal plugin set via an initializer, eg: config.plugins = [ :exception_notification, :ssl_requirement, :all ] then re-enable one at a time.
Specific causes:
From Ian Terrell: if you're using attachment_fu make sure you have the correct image processor installed. attachment_fu will require it even if you aren't attaching an image.
From Otto: make sure you didn't name a model that conflicts with a built-in Rails class, eg: Request.
From Josh Lewis: make sure you don't have duplicated class or module names somewhere in your application (or Gem list).
That is a tricky one.
What generally works for me is to run "script/console production" on the production server, and type in:
Announcement
That will usually give you a better error message. But you said you already tried that?
I just ran into this error as well.
The short of it was that my rb file in my lib folder was not in a folder structure to match my module naming convention. This caused the ActiveSupport auto loader to use the wrong module to see if my class constant was defined.
Specifically I had defined the following class
module Foo
class Bar
end
end
In the root of /lib/bar.rb
This caused the autoloader to ask module Object if Bar was defined instead of module Foo.
Moving my rb file to /lib/foo/bar.rb fixed this problem.
I've encountered this before, and the AttachmentFu plugin was to blame. I believe in my case it was due to AttachmentFu expecting a different image processor than what was available, or non-supported versions were also installed. The problem was solved when I explicitly added :with => :rmagick (or similar -- I was using RMagick) to the has_attachment method call even for non-image attachments. Obviously, make sure that your production environment has all the right gems (or freeze them into your application) and supporting software (ImageMagick) installed. YMMV.
As for not getting Rails and AttachmentFu to suck up and hide the real error -- we fixed it before figuring it out completely.
Since this is still the top Google result, I thought I'd share what fixed the problem for me:
I had a module in the lib folder with the exact same name as my application. So, I had a conflict in module names, but I also had a conflict of folder names (not sure if the latter actually makes a difference though).
So, for the OP, make sure you don't have duplicated class or module names somewhere in your application (or Gem list).
For me, the cause was a circular dependency in my class definitions, and the problem only showed up using autotest in Rails. In my case, I didn't need the circular dependency, so I simply removed it.
You can try disabling all your plugins and add them back in one by one.
In environment.rb in the Initalizer section, add a line like this one:
config.plugins = [ :exception_notification, :ssl_requirement, :all ]
Start with the minimum set to run your application and add them in one by one. I usually get this error when I've defined a model that happens to map to an existing filename. For example, a Request model but Rails already has a request.rb that gets loaded first.
I had this problem for a while and in my case the error was always preceded from this S3 error:
(AWS::S3::Operation Aborted) "A
conflicting conditional operation is
currently in progress against this
resource. Please try again."
This problem usually occurs when creating the same bucket over and over again. (Source AWS Developers forum)
This was due to the fact that I had used attachment_fu to create the bucket and I had decommented the line containing the command Bucket.create(##bucket_name) in lib/technoweenie/attachment_fu/backends/s3_backends.rb (near to line 152).
Once commented or deleted the command Bucket.create(##bucket_name) the problem disappeared.
I hope this helps.
Changing class names while using STI caused this for me:
Class changed from 'EDBeneficiary' to 'EdBeneficiary'
Existing records had 'EDBeneficiary' stored in the 'type' column, so when Rails tried to load them up the exception was raised.
Fix: Run a migration to update values in the 'type' column to match the new class name.
in my case, I am getting this error in the development console but I can load the class in irb
Sorry this isn't a definitive answer, but another approach that might work in some specific circumstance:
I just ran in to this problem while debugging a site using Ruby 1.8.7 and Merb 1.0.15. It seemed that the class in question (let's call it SomeClass) was falling out of scope, but when some_class.rb file was automatically loaded, the other files it required (some_class/base.rb etc) were not loaded by the require mechanism. Possibly a bug in require?
If I required some_class file earlier, such as the end of environment.rb, it seems to prevent the object falling out of scope.
I was getting this error duo to a controller definition being in a file that wasn't named as a controller. For instance, you have a Comment model and you define the controller in a comment.rb file instead of comments_controller.rb
I had this problem with rails version 1.2.3. I could reproduce the problem only with mongrel, using console environment access didn't give any useful info. In my case, I solved making the RAILS_ROOT/html folder writable by mongrel and then restarting the web server, as some users reported here:
http://www.ruby-forum.com/topic/77708
When I upgraded rails from 1.1.6 to 1.2.6 and 2.0.5 for my app, I faced this error. In short, old plugins caused this error. These plugins were already out-dated and no update anymore (even no repo!). After I removed them, the app worked on 1.2.6 and 2.0.5. But I didn't check the detail source code of the plugins.

Resources