Rails 2 route helpers in plugin - ruby-on-rails

I'm trying to write a plugin, and among the tasks I want to perform I want to be able to call route helper methods from within the plugin. For instance, if I have map.resources :user, I want to be able to call user_path(:id => 1) from my plugin. I keep getting undefined method user_path error.
In rails 3, you can do this using Rails.application.routes.url_helpers, but I don't seem to be able to find an alternative for rails 2. Including ActionController::UrlWriter does not help. Any ideas?

I'm using rails 2.3.4 and i can use my regular path helpers in the controllers and views of my plugins, at least within the ones i tested.
I can't use them in the lib files for the plugins, but that's because the helpers aren't available outside the controllers (the views are dealt with inside the controllers so they can use them too). The lib files (the meat of the plugins) tends to be modules and classes which get loaded into the model environment.
Can you provide more details about what you're trying to do?

You should be able to do:
app.user_path(1)

Related

Apipie Rails - How to document routes/controllers that are in gems (devise/devise_token_auth/etc.)

I'm creating a an API, that using Devise and devise_token_auth. Those controllers and controller files are in gems, so they're not actually in my project directory. I want to be able to add documentation for those routes (sign_up, sign_in, etc.) so people using the API can have docs.
Apipie provides a way of having documentation outside of a file, but it still requires you to include your doc file in the controller file, with include UsersModule. I dont have access to the controller file (well I could put it in my path, but i'd rather not).
Another solution is to create a RegistrationController with the same actions and then just never add a route for it. This seems like a bad practice.
How can I add Docs for controllers added via gems?

How to properly handle custom helper methods in a 'shared' folder?

I am using Ruby on Rails 3.2.2 and I would like to organize and share custom helper-view methods as-like I made for my view files. That is, in my app/views directory I have a shared folder where I put all shared templates and I would like to have a shared folder (intended to be used the same "sharing way" but for helper files) also in the app/helpers directory.
However, my doubts are:
Is right to share helper methods instead of putting those in the ApplicationHelper module (even if those helper methods are specific for shared views and not directly related to any model or controller)?
How can I load modules present in the app/shared/helpers directory in order to make those available to views?
Is there some prescriptions to this approach?
In Rails, helpers are actually global. Which means that you can call a user helper in a, say, posts view. So you don't really have to pollute ApplicationHelper, just divide them in the best way possible, and just use them normally.

How to extend Rails Engine's controllers properly?

I am developing Rails plugin (it is 3.1 Engine) called Carrier (https://github.com/stanislaw/carrier).
In one of my rails app I want to extend Carrier's controller with some new methods - fx. add new action #comment_form to Carrier::MessagesController (I want this action only exist in my app - I don't want to add it in Engine - because it is very specific).
Two strategies I see here:
1) I copy {Carrier's plugin root}/app/controllers/carrier/messages_controller.rb file to app/controllers/carrier/ folder of my app, and then extend it (all plugin's original actions are copied to rails app controllers folder too!).
2) More accurate way I want - is just to create {My rails app}/app/controllers/carrier/messages_controller.rb and write only #comment_form method I want Carrier to be extended with.
Expecting that two controllers's content (original from plugin's folder + custom in my rails app having only new #comment_form) will superpose, I tried the second way. But Rails then stopped recognizing all original Carrier's actions (#index, #show, etc...) written in messages_controller.rb from the Carrier plugin's folder and began treating rails app's messages_controller.rb version as the only one (all original actions began treated as empty and thus began rendered through rails conventions default flow).
So my question in general is:
How to add new actions to Rails Engines controllers without copying them entirely to Rails app/controllers folder?
UPD
For now I see two solutions which allow extension of engine's controllers without serious hacks (like this gem does: https://github.com/asee/mixable_engines from this thread: Extending controllers of a Rails 3 Engine in the main app)
1) load YourEngine::Engine.config.root + 'app' + 'controllers' + 'your_controller'
inside your_controller.rb that is in #{main_app}/app/controller/your_engine folder. Notice load instead of require.
2) Devise way (according to some SO topics suggest):
In main app create new controller that subclasses engine's one + edit routes to they point to this new controller.
I am still sure some even better solutions exist. Please correct me if they do!
Your option 2) is fine because it will let you upgrade the gem seamlessly.
Your current way simply overrides the existing controller.
Say you want to extend FooController.
Create a file named foo_controller_decorator.rb in your initializer folder
In the file:
FooController.class_eval do
#your additionnal code here.
end
I know this is a very old question but in case someone else finds this question, here is a gem that does decorators nicely. It hooks into Rails ActiveSupport and adds a convention to doing decorators that is safe from circular dependencies. We have been using it in production on multiple apps for a while.
https://github.com/EPI-USE-Labs/activesupport-decorators

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.

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