Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails models in subfolders and relationships

I organized some of my rails models in folders which I am autoloading with

config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]

I can use all models directly(e.g Image.first.file_name) but when I try to access them through relationships, e.g. @housing.images.each do... with has_many: images I get the following error

Unable to autoload constant Housing::HousingImage, expected /path/app/models/housing/image.rb to define it

How do i get rails to use my models for the relationship methods?

I'm running ruby 2.2 and rails 4.2

like image 516
Rene Koller Avatar asked Feb 19 '15 14:02

Rene Koller


1 Answers

Rails automatically loads models from subfolders but does expect them to have namespace.

/app/models/user.rb
class User
end

/app/models/something/user.rb
class Something::User
end

If you do not properly namespace your models in subfolders it will mess up Rails autoloader and cause errors like you see.

Remove this

config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]

And add the proper namespaces to your models and everything will work fine.

You can easily use namespaced models in your relationships like this:

class User
  has_many :photos, class_name: 'Something::Photo'
end

user.photos (will be instances of Something::Photo)

If you do not want to use the namespacing but split up your models for other reason, you can do that at the top-level and use other folders next to models. By default rails loads all the folders in apps, so you could just make a folder "models2" or whatever you want to call it next to "models". This will not have any effect on the functionality of the rails class loading.

Given your example you could then do:

/app
  /controllers
  /models
    for all your normal models
  /housing
    for your "housing" models

Like this you can directly access them at the top level namespace, no class_name settings or anything needed.

like image 104
maxigs Avatar answered Oct 14 '22 09:10

maxigs