How add new folder with class in rails app? - ruby-on-rails

I have 2 questions in rails app context:
I have some classes which aren't "modele", but require in my sytem, so I want separe them
1) How can I add "class' folder in app/? (if I create it and put classes, their are no included)
2) how can I put folder "model" in "app/class" folder (same thing here, the model are not included if I move it)
thx.

It´s kind of unclear what you are asking.
But if you want to autoload additional directories you can do it by placing something like this in config/application.rb
config.autoload_paths << Rails.root.join('app/class')
But please don´t call your directory class, use something descriptive instead.
By convention code that does not fit inside models, controllers, views, helpers or concerns and placed in the lib directory at the project root.
Edit:
You can load subdirectories by using a glob:
config.autoload_paths << Rails.root.join('app/classes/**/')

For quite some time Rails has autoloaded all paths under /app, as mentioned here
You may have run into a problem when using a "app/class" directory since "class" is a reserved word and "Class" is a class in Ruby.
There is a problem with your example:
exemple: "app/classes/effects/attribute.rb" with "class Effect::Attribute"
Notice that in the file path "effects" has an "s" at the end, whereas your module name does not "Effect::Atttribute". Those should match. Either both end with "s" or not, and when they do match Rails autoloading should work.
You should remove any of the other suggestions about appending to config.autoload_paths.

Related

Autoloading Rails models that don't follow the default file name structure

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.

what is the correct way to add classes to a controller in rails?

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.

Rails Module/Folder Naming Convention

I'm having a problem with a module name and the folder structure.
I have a model defined as
module API
module RESTv2
class User
end
end
end
The folder structure looks like
models/api/restv2/user.rb
When trying to access the class, I get an uninitialized constant error. However, if I change the module name to REST and the folder to /rest, I don't get the error.
I assume the problem has to do with the naming of the folder, and I've tried all different combos of /rest_v_2, /rest_v2, /restv_2, etc.
Any suggestions?
Rails uses the 'underscore' method on a module or class name to try and figure out what file to load when it comes across a constant it doesn't know yet. When you run your module through this method, it doesn't seem to give the most intuitive result:
"RESTv2".underscore
# => "res_tv2"
I'm not sure why underscore makes this choice, but I bet renaming your module dir to the above would fix your issue (though I think I'd prefer just renaming it to "RestV2 or RESTV2 so the directory name is sane).
You'll need to configure Rails to autoload in the subdirectories of the app/model directory. Put this in your config/application.rb:
config.autoload_paths += Dir["#{config.root}/app/models/**/"]
Then you should be able to autoload those files.
Also, your likely filename will have to be app/model/api/res_tv2/user.rb, as Rails uses String.underscore to determine the filename. I'd just call it API::V2::User to avoid headaches, unless you have more than one type of API.

Ruby on Rails delay in updating

I'm learning rails and I've come across a little quirk that I can't seem to find the answer to anywhere:
Since I'm learning rails, I'll make a few tweaks to the code while the localhost is running (rails s) and then just refresh the browser to see if the change I wanted to make was accurate. This works for changes to the views, css, html, routing, etc.
But now I'm making changes to a controller file that is calling another ruby class that I wrote and when I make changes to the ruby class, they don't show up right away. The way I know this is that I use a variety of printf functions in the Ruby class to show the current state of things and if I add one and re-run, it won't show unless I shut the server down and restart it.
Any thoughts? Is this a known issue?
You must autoload the folder which contains your custom files:
# in config/application.rb:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/extras)
There you write the folder which you want to be autoloaded.
WARNING: the naming is very important: files in there must be named as the class/modules they define (like models, controllers, etc):
foo.rb must define Foo costant
foo/bar.rb must define Foo:Bar costant
and you cannot autoload files which do not have this naming convention. The reason is linked to the autoload working: when in your code call f.e. the Foo constant, and the constant is missing, Rails tries to see if in its autoload paths there is a file that follows this naming convention, and if there is it loads it.

Ruby Rails Lib Folder Naming Convention

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.

Resources