Rails project organization with many models
I'm working on a rails app that is starting to have what seems (to me) to be a lot of models. There are 15 right now, but I'm thinking about adding 3-4 more to serve as "tag" like models (I need more functionality than Acts As Taggable offers).
So, the reason this bugs me a bi开发者_开发知识库t, is that 7 of the 15 models belong to a common parent. Several are belong_to, and a few are has_and_belongs_to_many. All the new models I'm contemplating would belong_to the same parent as well.
So, what I'm wondering is, what is the best "Railsy" way of organizing this kind of situation?
Instead of app/models
being super crowded with 6 "first-class" models and 10+ children of one of these, should/can I start using sub folders in my app folder? ie: app/models/parent/child.rb
?
I know this is kind of an open-ended question, but I would really appreciate advice as to the best way to handle a rails project with a proliferation of models.
Thanks!
You can do this, I always do :)
Just beware of something: if you create a folder which has the name of one your models, it will fail. Actually, Rails will think you want to extend it.
So in your model folder, prepend the name of your class with whatever fancy you want.
Example: if you want to put models related to users, put them in models/user_related/
You'll have to add this to your application.rb
file:
config.autoload_paths += Dir["#{Rails.root.to_s}/app/models/*"].find_all { |f| File.stat(f).directory? }
This will autoload all folders included in models
directory.
I think apneadiving's answer is good approach
Based on research with activesupport 3.0.11, there are some rules to follow when choosing a directory name however:
- The name must never match a constant in your system, or LoadError's could occur
- The name must be able to be converted to a valid constant name, or NameError's will occur.
Explanation of problem #1
Apneadiving's example of a directory name app/models/user_related works as long as a constant UserRelated is never used in your code. Otherwise a LoadError could potentially happen.
For example, assume there was a model called UserProfile and the first time rails sees the constant is in the UserRelated module. Rails will first try to load a UserRelated\:\:UserProfile constant and failing that a UserProfile constant.
If the user_profile file is at app/models/user_related/user_profile.rb, this matches the underscored path of UserRelated\:\:UserProfile and the file would be loaded expecting to define the UserRelated::UserProfile constant. This would raise the following error because it really defines the UserProfile constant.
Expected app/models/user_related/user_profile.rb to define UserRelated::UserProfile (LoadError)
This happens in the active support dependency code.
Explanation of problem #2
Another caveat is the directory name must be able turned into a valid ruby constant name (although to follow #1 the constant should be undefined). For example, if the directory name were app/models/user.related this would result in the following error inside the active_support dependency code:
wrong constant name User.related (NameError)
精彩评论