I would like to have a folder of related Models in my Rails 4 app. Why don't classes in app/models/debt_models get loaded?
I guess there is a work around by how come Rails just doesn't recursively go through folders under app/models? Is there a reason? Seems like this is something Rails should do without me having to tell Rails to do that.
You just have to follow conventions. If you put models in debt_models, it means you namespace them like:
module DebtModels
class Foo
Path: app/models/debt_models/foo.rb
Related
I am using namespacing in my Rails 5 app to try to keep resources organised.
I've been generating resources using the command line by adding the namespace folder to the generate command.
This makes a folder in the models folder for the main folder which the namespaced files are saved in.
I've since been reading posts from others that suggest namespacing models is not a good idea.
An example of what I currently have is:
class Stance::Assessment < ApplicationRecord
It seems to work alright so far.
What is the problem with namespacing models?
If it is a problem, does that mean I can't organise my models into folder groups, or does it mean that the model class doesnt need to be named wiht the "Stance::"?
There is a certain cost of complexity involved with "namespacing" your models. Ruby does not actually have true namespaces. Rather it has has modules which provide encapsulation.
Rails and ActiveRecord was designed around placing your application code in the Main object (the global object). While this might seem like a bad practice it is very simple and works well with the convention over configuration approach. It also allows a much simpler autoloading scheme and avoids the need to nest every single file in an additional folder.
Namespacing does have great organizational merits though and lets you avoid collisions. But there are a few minor aches in the backside:
table prefixes, having the generated table names like my_app_projects_tasks is really inconvenient when you need to write a custom join.
You need to override ActiveModel::Naming so that it does not look for paths like my_app_projects_tasks_path when using the polymorphic route helpers.
You need to explicitly set the class_name option when creating associations or override how ActiveRecord resolves constant names.
you can prefix your models, so instead of Stance::Assessment you would have StanceAssessment. not as clean as a namespace but it's pretty close to it
THE SHORT VERSION: How do I tell Rails to autoload an ActiveRecord class called ClassName that isn't located in the default location (app/models/class_name.rb). E.g. what if it's in app/models/subdirectory/class_name.rb and I don't want to rename the class to Subdirectory::ClassName?
THE LONGER VERSION:
I know that, by default in Rails, my class names have to follow a specific structure for Rails to be able to autoload them.
E.g. If my class is called Person, if I put it in app/models/person.rb, Rails can load it fine, but if I put it in e.g. app/models/person_class.rb, it can't. If I namespace it, e.g. Humanity::Person, I need to put it in the right folder app/model/humanity/person.
(Plus I can put classes in lib but I'll leave aside that detail for now)
So far so good. But what happens when I have a ton of ActiveRecord classes clogging up my app/models folder and I want to logically organise them into directory, but don't want to rename or namespace the actual classes? How can I tell Rails to autoload this classes?
Or is there a good reason why I shouldn't do this?
Add this line to config/application.rb
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**/}')]
Then you can use your model with their name as it is without name-spacing.
If i need to add (project specific) classes to my controler in rails, what is the correct way/place to put and "include" them/there .rb files? (quotes for: not the ruby keyword include)
I am new to rails, and did not find the correct way. LIB sounds like for more public libraries and - what I have learned - is not reloaded per default in dev mode.
sure, I could put all in controler.rb, but ...
the anser for me:
First: there are no rules, if you keep in mind (or learn like me) the rails rules:
NameOfCla -> name_of_cla(.rb) <-- not using class as word for clearence
name your class how you like:
class ExtendCon #<--- not using controller here for clearence
....
put it in a file extend_con.rb, wait for the path explaination, please. if you named your class 'MYGreatThing' it will be 'm_y_great_thing' (never testet that), so avoid chineese charachters
if your controller uses
#letssee=ExtendCon.new
rails learns that class and file (extend_con) on its own. i still did not figure out if a server restart is needed. (the first time)
choose the path to put the file: (I preferre Daves way) app/myexten or what you like, making it 'app' specific and still distquishes to standard rails 'things'
if you are not lasy like me (i put it in app/ontrollers)
put the path you have choosen into
config/application.rb like (comments are there to find it)
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/app/controllers)
config.autoload_paths += %W(#{config.root}/app/myexten)
this one workes for me in all modes including "developer" and i did not need to put "my own" things in app/lib
It depends.
I tend to put library code used explicitly (e.g., instantiated, injected, etc. into app-level artifacts) into app/xxx where xxx signifies the "type" of thing, like decorators, services, etc.
Magic stuff tends to end up in lib, like monkey patches, architectural-level artifacts, and so on.
Code anywhere can be added to the autoload paths, required automatically by an initializer, etc.
Rails 4 comes with an internal directory for controllers called concerns. You could try using that.
app/controlls/concerns
If you have concerns/foo_bar.rb, you include it as follows:
class FooController < ApplicationController
include FooBar
end
Models also have their own concerns directory. I find this approach useful, and it can be applied to Rails 3. You just have to add the directories to your load paths.
I have a file in my Rails 3.2.11 project called app/queries/visible_discussions.rb which looks like the following:
class VisibleDiscussions
...
end
I'd like to namespace the query so that I can call it using something like Queries::VisibleDiscussions so I tried to do the following:
module Queries
class VisibleDiscussions
...
end
end
However, I'm getting a uninitialized constant Queries (NameError) when I try to call Queries::VisibleDiscussions from the rails console.
Any ideas?
if you add lib to your autoload_paths then it will respect the namespacing under lib - lib/query/visible_discussions.rb
or create a new dir under app - say src and then nest your code there - app/src/query/visible_discussions.rb
i would use the 3rd style in your post for either of these, i.e.
module Query
class VisibleDiscussions
...
end
end
both of these solutions are annoying to me, there might be a way to tell rails to namespace directories under app, but i have no clue how it would be done
Rails needs to know what directories to load (a part from the defaults). Try:
#config.application.rb
config.autoload_paths += %W(#{config.root}/queries)
I seem to be having trouble with the naming conventions of the Lib Folder in Rails, and the error messages provided to me do not help. [For example, I have received a message saying that XXX::YYY::TextBox is expected to be defined xxx/yyy/text_box.rb, even though it clearly was defined there.] I think I'm getting the convention wrong.
Let's say I am working on YourModule::MyModule::MyClass. I clearly get that this file should be located in
lib/your_module/my_module/my_class.rb
But what should the actual file here look like? Which one of these (if either) are correct?
#your_module/my_module/my_class.rb
module YourModule
module MyModule
class MyClass
...
end
end
end
Or
#your_module/my_module/my_class.rb
class MyClass
...
end
In other words, do I need to nest the class inside of the module structure or not?
The lib folder has few conventions, as it is not autoloaded. So, how you organize the files is up to you, but you do have to name the classes correctly. Your first example is correct.
To get the files included you need to specify you want them in your application.rb file, see this example: Best way to load module/class from lib folder in Rails 3?
I would recommend making a folder just called lib/modules, since you probably won't have very many. Name the file my_class.rb. Then in application.rb you need:
config.autoload_paths += %W(#{config.root}/lib/modules)
That should take care of your issue.