Rails models in subfolders and relationships

2019-04-28 09:34发布

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

1条回答
姐就是有狂的资本
2楼-- · 2019-04-28 10:14

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.

查看更多
登录 后发表回答