如何一般地捕获实例?

时间:2014-08-22 02:47:55

标签: ruby-on-rails

我正在使用Rails 3.2.19Ruby 2.1.2。我一直在谷歌上搜索想出来,但也许我不是在寻找正确的事情。无论如何,我会尽量简洁。

我有一些不同的模型都具有name属性。在我的视图中,无论传递到视图中的实例名称如何,我都希望以某种方式能够访问name属性。目前,我的各种控制器创建了各自模型的实例。例如:

class PagesController < ApplicationController
  def show
    @page = Page.find(params[:id])
    respond_to do |format|
      format.html
    end
  end
end

-

class ProductsController < ApplicationController
  def show
    @product = Product.find(params[:id])
    respond_to do |format|
      format.html
    end
  end
end

虽然我理解我可以简单地将实例重命名为通用的,但我想知道是否有某种方法可以访问任何/所有实例,同时保持明确的实例名称。

基本上是这样的:

page.html.haml

%h1= resources[0].name #equates to @page.name
%h2= @page.some_other_attribute

product.html.haml

%h1= resources[0].name #equates to @product.name
%h2= @product.price

上述resources[0]中的每一个@page@product

2 个答案:

答案 0 :(得分:0)

您必须为通用控制器定义带有额外resource_type参数的路由,否则只需将resource_type包含在url查询参数中

/resources/product/17
or
/resources/17?resource_type=product

这将允许您在控制器中执行以下操作

class ResourcesController < ApplicationController
  def show
    @resource = find_resource(params)
    respond_to do |format|
      format.html
    end
  end

  private
  def find_resource(params)
    resource_klass = {
      product: Product, 
      page: Page
    }[params[:resource_type]]

    resource_klass.find(params[:id])
  end
end

另一个选项是引入另一个ResourceType实体并定义多态:has_one:belongs_to与实际资源实体(product,page)的关联。然后始终搜索ResourceTypes并加载多态资源实体

class ResourceType < ActiveRecord::Base
  belongs_to :resource, polymorphic: true
end

class Product < ActiveRecord::Base
  has_one :resource_type, as: :resource
end

 class Page < ActiveRecord::Base
  has_one :resource_type, as: :resource
  end


product_resource_type = ResourceType.create(...)
product = Product.create(resource_type: product_resource_type)

page_resource_type = ResourceType.create(...)
page = Page.create(resource_type: page_resource_type)


ResourceType.find(product_resource_type.id).resource
=> product

ResourceType.find(page_resource_type.id).resource
=> page

答案 1 :(得分:0)

在发现instance_variablesinstance_variables_get

后,我发现了这一点

这些方法将返回传递给视图的所有实例变量。从那里我发现:@_assigns实例变量包含我正在寻找的实例。所以我迭代它们以查找是否有name属性。

- instance_variable_get(:@_assigns).each do |var|
  - if var[1].respond_to?("name")
    %h1= var[1].name

可能有更好的方法来实现这一点,所以如果有人有任何意见,欢迎他们。