Jellicle
Jellicle

Reputation: 30206

Ruby: importing two modules/classes of the same name

When my system requires two classes or modules of the same name, what can I do to specify which I mean?

I'm using rails (new to it), and one of my models is named "Thread". When I try to refer to the class "Thread" in thread_controller.rb, the system returns some other constant of the same name.

<thread.rb>
class Thread < ActiveRecord::Base

  def self.some_class_method
  end

end

<thread_controller.rb>
class ThreadController < ApplicationController

  def index
    require '../models/thread.rb'
    @threads = Thread.find :all
  end

end

When I try Thread.find(), I get an error saying that Thread has no method named find. When I access Thread.methods, I don't find my some_class_method method among them.

Any help? (And don't bother posting "just name your model something else." It's not helpful to point out obvious compromises.)

Upvotes: 3

Views: 2739

Answers (3)

Reactormonk
Reactormonk

Reputation: 21690

You could put your app into its own namespace.

<my_app/thread.rb>
module MyApp
  class Thread
  end
end

Upvotes: 2

bowsersenior
bowsersenior

Reputation: 12574

If you absolutely must overwrite an existing constant, you can do something like this:

# use Object to make sure Thread is overwritten globally
# use `send` because `remove_const` is a private method of Object
# Can use OldThread to access already existing Thread
OldThread = Object.send(:remove_const, :Thread)

# define whatever you want here
class MyNewThread 
  ...
end

# Now Thread is the same as MyNewThread
Object.send(:const_set, :Thread, MyNewThread)

Obviously anything that relied on the pre-existing Thread would be busted unless you did some kind of monkey-patching.

Just because this kind of thing can be done, doesn't mean it should be. But in certain circumstances it can be handy, for example in tests you can override a remote data source with your own 'dumb' object.

Upvotes: 2

Ryan Bigg
Ryan Bigg

Reputation: 107708

No really, name your model something else.

Thread is a reserved constant in Ruby and overriding that constant is only going to make you run into trouble. I compromised for my application and called it Topic instead.

Upvotes: 2

Related Questions