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

发布于 2024-12-03 15:24:22 字数 1104 浏览 9 评论 0原文

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

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

以下方式(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

有更好的方法吗?

编辑

我正在执行一个操作。该路径采用 parent_model/:id/picture/new 的形式,参数包含父 ID(employee_idproduct_id)。

I'm trying to find an elegant (standard) way to pass the parent of a polymorphic model on to the view. For example:

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

The following way (find_imageable) works, but it seems "hackish".

#PictureController (updated to include full listing)

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

Is there a better way?

EDIT

I'm doing a new action. The path takes the form of parent_model/:id/picture/new and params include the parent id (employee_id or product_id).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

揽月 2024-12-10 15:24:22

我不确定你到底想做什么,但如果你想找到“拥有”图片的对象,你应该能够使用 imageable_type 字段来获取类名。您甚至不需要辅助方法,只需

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

更新
对于索引操作,您可以这样做

def index
  @pictures = Picture.includes(:imagable).all
end

,这将为您实例化所有“imagables”。

更新二:保利之怒
对于您的新方法,您可以将 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

您当然可以在控制器中定义一个包含可能的父级的常量,并使用它来代替在方法中明确列出它们。对我来说,使用请求路径对象感觉更“Rails-y”。

I'm not sure exactly what you're trying to do but if you're trying to find the object that 'owns' the picture you should be able to use the imageable_type field to get the class name. You don't even need a helper method for this, just

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

Update
For an index action you could do

def index
  @pictures = Picture.includes(:imagable).all
end

That will instantiate all 'imagables' for you.

Update II: The Wrath of Poly
For your new method you could just pass the id to your constructor, but if you want to instantiate the parent you could get it from the url like

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

You could of course define a constant in your controller that contained the possible parents and use that instead of listing them in the method explicitly. Using the request path object feels a little more 'Rails-y' to me.

逆光飞翔i 2024-12-10 15:24:22

我刚刚遇到了同样的问题。

我“某种程度上”解决这个问题的方法是在每个具有多态关联的模型中定义一个 find_parent 方法。

class Polymorphic1 < ActiveRecord::Base
  belongs_to :parent1, :polymorphic => true
  def find_parent
    self.parent1
  end
end

class Polymorphic2 < ActiveRecord::Base
  belongs_to :parent2, :polymorphic => true
  def find_parent
    self.parent2
  end
end

不幸的是,我想不出更好的方法。希望这对您有一点帮助。

I just ran into this same problem.

The way I 'sort of' solved it is defining a find_parent method in each model with polymorphic associations.

class Polymorphic1 < ActiveRecord::Base
  belongs_to :parent1, :polymorphic => true
  def find_parent
    self.parent1
  end
end

class Polymorphic2 < ActiveRecord::Base
  belongs_to :parent2, :polymorphic => true
  def find_parent
    self.parent2
  end
end

Unfortunately, I can not think of a better way. Hope this helps a bit for you.

眼中杀气 2024-12-10 15:24:22

这是我对多个嵌套资源执行的方法,其中最后一个参数是我们正在处理的多态模型:(与您自己的仅略有不同)

def find_noteable
  @possibilities = []
  params.each do |name, value|
    if name =~ /(.+)_id$/  
      @possibilities.push $1.classify.constantize.find(value)
    end
  end
  return @possibilities.last
end

然后在视图中,如下所示:

<% # Don't think this was needed: @possibilities << picture %>
<%= link_to polymorphic_path(@possibilities.map {|p| p}) do %>

返回最后一个参数的原因数组是为了允许查找有问题的子/多记录,即@employee.pictures或@product.pictures

This is the way I did it for multiple nested resources, where the last param is the polymorphic model we are dealing with: (only slightly different from your own)

def find_noteable
  @possibilities = []
  params.each do |name, value|
    if name =~ /(.+)_id$/  
      @possibilities.push $1.classify.constantize.find(value)
    end
  end
  return @possibilities.last
end

Then in the view, something like this:

<% # Don't think this was needed: @possibilities << picture %>
<%= link_to polymorphic_path(@possibilities.map {|p| p}) do %>

The reason for returning the last of that array is to allow finding the child/poly records in question i.e. @employee.pictures or @product.pictures

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文