Rails 3:在控制器中找到多态模型的父级?

Nav*_*Nav 12 polymorphic-associations ruby-on-rails-3

我正在尝试找到一种优雅(标准)的方法来将多态模型的父级传递给视图.例如:

class Picture < ActiveRecord::Base
  belongs_to :imageable, :polymorphic => true
end

class Employee < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end 

class Product < ActiveRecord::Base
  has_many :pictures, :as => :imageable
end
Run Code Online (Sandbox Code Playgroud)

以下方式(find_imageable)有效,但似乎"hackish".

#PictureController(已更新,包括完整列表)

class PictureController < ApplicationController
  #/employees/:id/picture/new
  #/products/:id/picture/new
  def new
    @picture = imageable.pictures.new
    respond_with [imageable, @picture]
  end

  private
  def imageable
    @imageable ||= find_imageable
  end

  def find_imageable 
    params.each do |name, value|
      if name =~ /(.+)_id$/  
        return $1.classify.constantize.find(value)  
      end  
    end  
    nil
  end
end
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

编辑

我正在做一个new动作.路径采用的形式parent_model/:id/picture/new和params包括父id(employee_idproduct_id).

dog*_*unk 6

我不确定你要做什么,但如果你想找到'拥有'图片的对象,你应该可以使用imageable_type字段来获取类名.你甚至不需要帮助方法

def show
  @picture = Picture.find(params[:id])
  @parent = @picture.imagable
  #=> so on and so forth
end
Run Code Online (Sandbox Code Playgroud)

更新 对于您可以执行的索引操作

def index
  @pictures = Picture.includes(:imagable).all
end
Run Code Online (Sandbox Code Playgroud)

这将为你实现所有"想象力".

更新II:Poly的愤怒 对于你的新方法,你可以将id传递给你的构造函数,但如果你想实例化父类,你可以从url中获取它

def parent
  @parent ||= %w(employee product).find {|p| request.path.split('/').include? p }
end

def parent_class
  parent.classify.constantize
end

def imageable
  @imageable ||= parent_class.find(params["#{parent}_id"])
end
Run Code Online (Sandbox Code Playgroud)

您当然可以在控制器中定义一个包含可能父项的常量,并使用它而不是明确地在方法中列出它们.使用请求路径对象对我来说感觉更多'Rails-y'.