Using /lib/ Subdirectories in Rails - for View Content - ruby-on-rails

This is an evolving issue related to a previous posting I made...
I am playing around some - to try to learn how the /lib/ directory in Rails works - and how to reference variables defined in the /lib/ directory for use in a view.
I have a file called helloworld.rb and it's saved in a /lib/hellotest/ directory in Rails.
The helloworld.rb file has the following code:
module HelloWorld
def hello
#howdy = "Hello World!"
end
end
I want to be able to display the results of this method on a view called index.html.erb, so I include the following code in the index_helper.erb file:
module IndexHelper
require 'helloworld'
end
I have learned that I need to include the following line of code in the /config/application.rb file:
config.autoload_paths += %W(#{Rails.root}/lib/hellotest/)
Also, I include the following code on the view index.html.erb:
<%= #howdy %>
I think I may have found something that is causing problems. I didn't want to load the entire /lib/ directory at startup so I put the file in a subdirectory called /lib/hellotest/. I've read there are some issues with how Rails interprets module/class naming conventions in the lib folder, but I can't quite figure it out. I see a good resource regarding this possible solution to my problem on William B Harding's Blog, on point 2 - but I can't quite get my arms around this solution as it pertains to my problem.
Any advice please?
What am I missing?

I'd suggest that unless you have a good reason to do otherwise, follow the conventional naming for modules and classes (as described in the link you provided). Rename helloworld.rb to hello_world.rb, move it into lib, and change your autoload_paths to:
config.autoload_paths += %W(#{Rails.root}/lib/)
Finally, change require 'hello_world' to require 'hello_world' in your IndexHelper module. It should then load normally.

Related

How add new folder with class in rails app?

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.

Rails: Can't access a module in my lib directory

I'd like to create a general purpose string manipulation class that can be used across Models, Views, and Controllers in my Rails application.
Right now, I'm attempting to put a Module in my lib directory and I'm just trying to access the function in rails console to test it. I've tried a lot of the techniques from similar questions, but I can't get it to work.
In my lib/filenames.rb file:
module Filenames
def sanitize_filename(filename)
# Replace any non-letter or non-number character with a space
filename.gsub!(/[^A-Za-z0-9]+/, ' ')
#remove spaces from beginning and end
filename.strip!
#replaces spaces with hyphens
filename.gsub!(/\ +/, '-')
end
module_function :sanitize_filename
end
When I try to call sanitize_filename("some string"), I get a no method error. When I try to call Filenames.sanitize_filename("some string"), I get an uninitilized constant error. And when I try to include '/lib/filenames' I get a load error.
Is this the most conventional way to create a method that I can access anywhere? Should I create a class instead?
How can I get it working? :)
Thanks!
For a really great answer, look at Yehuda Katz' answer referenced in the comment to your question (and really, do look at that).
The short answer in this case is that you probably are not loading your file. See the link that RyanWilcox gave you. You can check this by putting a syntax error in your file - if the syntax error is not raised when starting your app (server or console), you know the file is not being loaded.
If you think you are loading it, please post the code you are using to load it. Again, see the link RyanWilcox gave you for details. It includes this code, which goes into one of your environment config files:
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]
But really, read Yehuda's answer.

uninitialized constant GamesController::GamesAccounts

created a games_account.rb file in the library folder. The following is the structure
module GamesAccounts
class GamesAccountsClient
.
.
.
.
.
end
end
trying to do GamesAccounts::GamesAccountsClient.new in the controller gives me the error
uninitialized constant GamesController::GamesAccounts
I have even added
config.autoload_paths += %W(#{config.root}/lib) in the applications.rb
Am i doing anything wrong here?
I'm not sure about this, but I think you might need to put it in lib/games_accounts/games_accounts_client.rb instead of what you have now, which I presume is lib/games_account.rb. The idea is it should be lib/<module name>/<class name>.rb.
The problem is in your file, name it games_accounts.rb instead of games_account.rb and it should work (because it will match the module name).
If you plan to put many classes within this module, create a directory named games_accounts, and add the class there with the mapping of each file to each class, and put it on your application.rb file, like
config.autoload_paths += %W(#{config.root}/lib/games_accounts)
I have a other thought, If your file is something which is be helping the models than try having it in the form of concerns folder and adding your file there. Since Rails 4 onwards all these support activities will be taken by concerns it's good to adopt right away. Have a read at the blog post by DHH also:
http://37signals.com/svn/posts/3372-put-chubby-models-on-a-diet-with-concerns

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.

What is the simplest way to make a group of methods available to several Rails applications

tl;dr
What's a simple way I can create a view helpers module I can use in many apps?
What file, located where, loaded how?
I'm on Rails 2.3.11.
I have a bunch of view helper methods. Here's an example of one of them:
# Render form input fields to add or edit a ZIP code.
def render_zip_code_fields( model_instance )
# Bla bla bla ...
end
I have about 20 or so that I've developed over the years and often use in various applications. I'd like to wrap them all up in one file that I can just drop into and app and then be able to call them in my views.
Why not just copy-and-paste them into application_helper.rb? That just doesn't feel right to me. It seems like it should be a separate file.
In fact I tried creating in /lib...
# /lib/my_view_helpers.rb
module MyViewHelpers
# ...
end
And then in application_helper.rb I put...
include MyViewHelpers
But I got a lot of "uninitialized constant MyViewHelpers errors. Maybe a syntax error? I don't think I need to require my_view_helpers.rb first because it's in /lib. Everything in there gets loaded automatically, right?
So what's the right way to do this optimizing for simplicity?
Sorry this is so long. I get verbose when I'm tired.
As of Rails 3, /lib is no longer on the default load path. You will need to put the following line in the Application class in config/application.rb.
config.autoload_paths += ["#{config.root}/lib"]
An alternative would be to drop the file in app/helpers since it is a helper, after all.

Resources