3limin4t0r
3limin4t0r

Reputation: 21130

Is there a clean way to find a polymorphic instance of an object in a nested controller?

I'm working with a nested controller using models with a polymorphic relations. I was wondering if there is a clean way to to find @holder. The code in CommentsController#set_holder is ugly and I was wondering if rails provides helpers for this issue.

class Comment < ActiveRecord::Base
  belongs_to :holder, polymorphic: true
end

class Product < ActiveRecord::Base
  has_many :comments, as: :holder
end

class User < ActiveRecord::Base
  has_many :comments, as: :holder
end

Dummy::Application.routes.draw do
  resources :products do
    resources :comments
  end

  resources :users do
    resources :comments
  end
end

class CommentsController < ApplicationController
  before_action :set_holder, only: [:new, :create]

  # code ...

  def new
    @comment = @holder.comments.build
  end

  # code ...

  private

  def set_holder
    # params = {"controller"=>"comments", "action"=>"new", "user_id"=>"3"}
    # or
    # params = {"controller"=>"comments", "action"=>"new", "product_id"=>"3"}
    # Is there a Rails way to set @holder?

    type, type_id = params.find { |k,_| /_id$/ === k }
    @holder = type.sub(/_id$/, '').classify.constantize.find(type_id)
  end
end

Upvotes: 0

Views: 147

Answers (1)

wbucko
wbucko

Reputation: 95

You can try with:

resource, id = request.path.split('/')[1, 2]
@holder = resource.classify.constantize.find(id)

Also in routes you can make things shorter by:

resources :users, :products do
  resources :comments
end

Upvotes: 1

Related Questions