4

I have a tirable orgnizing my Models in a Sinatra project.

Let's say I have 2 models: Post and Comment, nn Post model, I have to call Comment model. And now I have <class:Post>': uninitialized constant Comment (NameError).

I know its an issue in ordering the requiring for the models, but what about if I have lots of models? What's the Rails way in requiring models, etc.?

UPDATE

I use this code to auto_load my models in Sinatra/Rack/Grape applications. This code should be at the top of your code ie in the boot file.

models = File.join(File.dirname(__FILE__), 'app', 'models') # path to your models
$LOAD_PATH << File.expand_path(models)

# Constent Missing for requiring models files
def Object.const_missing(const)
    require const.to_s.underscore
    klass = const_get(const)
    return klass if klass
end
amrnt
  • 1,331
  • 13
  • 30
  • Phrogz answer here might be of help to you: http://stackoverflow.com/questions/5015471/using-sinatra-for-larger-projects-via-multiple-files/5030173#5030173 – Paul Hoffer Jul 28 '11 at 07:54

3 Answers3

4

You should put all of your models in a folder, such as lib in your application, then you can add this to the top of your Sinatra app file:

$: << File.dirname(__FILE__) + "/lib" # Assuming app.rb is at the same level as lib

require 'post'
require 'comment'

You should organise your code so that you do not call other models until all model declarations are loaded.

stef
  • 14,172
  • 2
  • 48
  • 70
  • 1
    What if i have a punch of models? the structure of my app is ["app.rb", "controllers/*", "models/*"] and all of this are in lib folder. and I require them in `config.ru` by `Dir["lib/**/*"].each { |f| require f if File.extname(f) =~ /\.rb/ }` – amrnt Jul 20 '11 at 19:24
  • Sure - it's just a bit magical. I prefer to have code that I and others can read and understand. "Where is 'Post' required? Search for it... hmmm..." – stef Jul 20 '11 at 19:33
  • Okay. In your code above, if I called `Comment` in `Post` model, will it raise an error? – amrnt Jul 20 '11 at 20:13
  • No, it should be fine, but you'd need to post your code to verify that. – stef Jul 20 '11 at 20:32
  • Yes. Here is in this gist! My model: https://gist.github.com/be46a7aa54d5b5454d1b in addition theres `post.rb`. if `comment.rb` loaded before `post.rb` this is a problem! – amrnt Jul 23 '11 at 22:22
  • This is quite specific then - you're using a 'voteable' module and it requires a model class to be sent as an option when you do `voteable...`. You could try `def self.included(c); super(c); class << c; voteable Post, :up => +2, :down => -2; end; end;` Gah - there is no multi-line commenting here. Replace ; with newlines. – stef Jul 24 '11 at 14:32
  • But when I deploy multiple files to heroku it failed to load those files. What could be the problem? – toy Dec 24 '11 at 03:21
3

The Rails way is based on a very nice Ruby feature: const_missing. You could write your const_missing method or looking around the web for a solution with const_missing and sinatra.

lucapette
  • 20,564
  • 6
  • 65
  • 59
0

no prob when I tried this

a Comment if it is in a method of Post shouldn't be actually evaluated there must be some circumstance triggering the NameError

don't call Post in the body of the class declaration load all the model files per the first commenter's suggestion

shouldnt be having the same reference troubles as Java per se in a dynamic lang like Ruby

han
  • 175
  • 2