0

I am using Ruby on Rails 3.2.2 and I would like to know if it is possible to "map" a controller action to another controller action but changing some parameter. That is, I have followings models and controllers:

# File system:
# /app/models/articles/user_association.rb
# /app/models/users/article_association.rb
# /app/controllers/users/article_associations_controller.rb
# /app/controllers/articles/user_associations_controller.rb


# /app/models/articles/user_association.rb
class Articles::UserAssociation < ActiveRecord::Base
  ...
end

# /app/models/users/article_association.rb
class Users::ArticleAssociation < Articles::UserAssociation # Note inheritance
  #none
end

# /app/controllers/users/article_associations_controller.rb
class Articles::UserAssociationsController < ApplicationController
  def show
    @articles_user_association = Articles::UserAssociation.find(params[:article_id])
    ...
  end

  def edit
    @articles_user_association = Articles::UserAssociation.find(params[:article_id])
    ...
  end

  ...
end

# /app/controllers/articles/user_associations_controller.rb
class Users::ArticleAssociationsController < ApplicationController
  def show
    # It is the same as the Articles::UserAssociationsController#show 
    # controller action; the only thing that changes compared to 
    # Articles::UserAssociationsController#show is the usage of 
    # 'params[:user_id]' instead of 'params[:article_id]'.
    @users_article_association = Users::ArticleAssociation.find(params[:user_id])
    ...
  end

  def edit
    # It is the same as the Articles::UserAssociationsController#edit
    # controller action; the only thing that changes compared to  
    # Articles::UserAssociationsController#edit is the usage of
    # 'params[:article_id]' instead of 'params[:user_id]'. 
    @users_article_association = Users::ArticleAssociation.find(params[:user_id])
    ...
  end

  ...
end

So, I would like to handle HTTP requests directed to the /users/:user_id/article path as the controller action related to the /articles/:article_id/user path.

Note: I would like to make that in order to DRY (Don't Repeat Yourself) code, but, as said previously, the only thing that change between Users::ArticleAssociationsController and Articles::UserAssociationsController#show is params.

Is it possible?

tereško
  • 58,060
  • 25
  • 98
  • 150
Backo
  • 18,291
  • 27
  • 103
  • 170

1 Answers1

0

You not only modify the parameters, but you alter the class you want to find.

@users_article_association = Users::ArticleAssociation.find(params[:user_id])
# and
@users_article_association = Articles::UserAssociation.find(params[:article_id])

They are quite different. I suggest you to handle these differences, and then extract the real common code to another method, and call that from both sides.

Matzi
  • 13,770
  • 4
  • 33
  • 50
  • Practically speaking, `Users::ArticleAssociation` and `Articles::UserAssociation` are the *same* since class inheritance. However, you solution could be right. – Backo Jul 13 '12 at 13:40
  • How does your `find` method knows what kind of id it gets? You only pass a number to it, if the two class are the same, then the id is either used as a user id or an article id in every case, no matter what are you looking for. – Matzi Jul 14 '12 at 13:01