Where should Rails 3 custom validators be stored? - ruby-on-rails

I've seen docs/websites show that custom validators should go in a /lib or /lib/validators directory of a project. I've found (by reading an answer to another post) that they only seem to work in config/initializers. Does anyone know, or have a pointer to official documentation that shows where custom validators should live?

If you place your custom validators in app/validators they will be automatically loaded without needing to alter your config/application.rb file.

If you add this to your /config/application.rb file:
config.autoload_paths += %W["#{config.root}/lib/validators/"]
Then Rails will automatically load your validators on start up (just like /config/initializers/), but you keep the clean structure of having your validators in one nice, well named spot.

lib/validators seems by far the cleanest. However you may need to load them in before your models, so probably from an initializer.

Here's the official docs about custom validations. AFAIK its a good practice to keep them in the relevant models.

Related

Rail 3 custom renderer: where do put this code?

I'm following along with Yehuda's example on how to build a custom renderer for Rails 3, according to this post: http://www.engineyard.com/blog/2010/render-options-in-rails-3/
I've got my code working, but I'm having a hard time figuring out where this code should live. Right now, I've got my code stuck right inside of my controller file. Doing this, everything works. When I move the code to the lib folder, though, I have explicitly 'require' my file in the controller that needs the renderer or it won't work. Yes, the file gets loaded when it sits in the lib folder, automatically. but the code to add the renderer isn't working for some reason, until I do a require on it.
where should I put my code to add the renderer and mime type, so that rails 3 will pick it up and register it for me, without me having to manually require the file in my controller?
I'd put it in an initializer, or in lib and require it in application controller.
In Jose Valim's book, Crafting Rails applications, this is the first chapter. He creates a PDF mime type & renderer using Prawn.
In his example, he created lib/pdf_renderer.rb with this:
require "action_controller"
Mime::Type.register "application/pdf", :pdf
Since lib is no longer autoloaded, you'll either have to autoload lib or specifically require this file where you want to use it.
An initializer might also be appropriate here.
i did some more digging around on this based on the suggestions here.
i found a "mime_types" initializer was already in our code base. i think this is created by rails, by default. it had several commented out examples in it. so i added my custom mime type to this file.
i also decided to use an initializer for the custom renderer so that it's automatically loaded and available with the app. this way i don't have to remember to include it in the various places i need it. i can just respond_to the format i created, and send the data down.
thanks for the tips, everyone.

Where should libraries go in Rails 3?

Where's the recommended location for libraries in Rails 3? Is it as simple as 'lib'?
I'm not sure because 'lib' seems more like a Rails 2 remnant, especially considering that it's no longer auto-loaded (and there was a lot of discussion about that, apparently).
Initializers are more for (obviously) initialization tasks such as overrides.
Specifically I have a small module for attachment handling (Paperclip doesn't fit here) that's too large and distinct to include in my model, but not generic or worthwhile enough to implement as a gem.
From a functionality standpoint it lives somewhere in the middle among the model, view, and controller. This makes it sound like a helper, but in Rails helpers are intended for views AFAIK.
Should I just put it in 'lib' and autoload it in application.rb? Or maybe I could create a custom form builder to handle the presentation (or both).
I know how to make it work, but I'm hoping to learn something new. :)
lib is still the right place to put these kind of things.
Autoloading lib was removed in Rails 3 because of the way engines work, but mainly because it's easy to just add it to the autoload_paths if you do want it automatically loaded and if not, you can require as needed. lib is still in the load path, so you don't need to specify where the module or class you're requiring is.
You're correct, helpers are intended for the view, and would not be the place to put any model-related logic.
I'd put the module in lib, and require and include it in your model as needed.

How can I make some code available throughout a Rails app conveniently?

I want to add a library that I wrote to a Rails app (and to other Rails apps later). I tried putting it in /lib which seemed logical...
[RAILS_ROOT]/lib/my_lib/the_main_file.rb
[RAILS_ROOT]/lib/my_lib/some_other_file.rb
Then...
require 'my_lib/the_main_file'
That works fine.
But is that a great way to do it?
Now I have to put that require everywhere I want to call the library.
I thought about putting the require in an initializer but that seems kind of weird.
What do people usually do about this?
Using an initializer may look weird when you have a single file to include, but sometimes I have many files that I want to add, and end up using an intializer that only includes stuff. It's actually pretty neat.
I'm not sure about the "best practices"(tm) or anything, but we do a similar thing for our project as well. The library is in lib, and the require in an initializer (app_config.rb in our case). This seems like a good way to do things, and hasn't bitten us in the butt thus far :) Hope that helps.
I usually wrap up my stuff in classes. If you add config.autoload_paths += %W(#{config.root}/lib) to your application.rb then any reference to a missing constant will result in an attempt to autoload it, i.e just using MyClass.new will make it try to load `lib/my_class.rb'.
Have a look at Best way to load module/class from lib folder in Rails 3?

Should I put constants for my Rails project in environment.rb?

I want to store a path for a special directory used by my Rails application. Should I store that in environment.rb, or is there another place this is meant to go?
THE_DIRECTORY_PATH = '/path/to/directory'
Let's assume my controllers + models or libraries in /lib need access as well.
How about storing it in a YAML configuration file that gets loaded by an initializer? This Railscast has the details.
Use a robust YAML-file approach that allows per-environment settings. Try app_config, which has loads of great features, including referring syntax like AppConfig.the_directory_path.
If controllers need access to it, then a better place would be the ApplicationController.

Creating Plugins in rubyonrails

I am creating a plugin which involves a controller, model & views. while i can move these files from the vendor/plugin directory to app/controllers, models & views respectively.
now i can run my controller & model just by copying them in lib folder of vendor/plugins/plugin_name/lib and they are directly accessible, but my views are not initialized from there, so i need a technique which can make my views in vendor/plugins/plugin_name/lib/views accessible to rails framework without copying.
i am trying to add them to actionview, but not sure how to do that.
please guide me on this.
There's ways you can add your plugin's views directory to the "search path" for ActionView, but the easiest way to handle all this is to just use something like the Rails Engines plugin to do all the hard work for you.
If you're looking to add models, views and controllers via a plugin, take a look at Desert: http://github.com/pivotal/desert. I'm not too keen on this approach, but Desert seems to work for people who like it.

Resources