Rails 3:使用不同的帖子类型(图像,链接,文本,视频)创建帖子模型。我应该使用什么样的继承?

时间:2012-10-15 18:47:29

标签: ruby-on-rails ruby-on-rails-3

我正在整理一个允许用户发帖的应用。每个帖子都有一个类型(图像,视频,链接,文本),包含相似和唯一的变量。我想通过不同的形式在整个网站上提供的“作曲家”中提交这些内容。

这是帖子模型,图库:

class Gallery < ActiveRecord::Base
    attr_accessible :name, :asset
    has_attached_file :asset, :styles => { :small => '160x120#', :medium => "500x", :thumb => "300x200#" }
    belongs_to :user
    has_many :likes
    validates :user_id, presence: true
    validates :type, presence: true
    validates :name, presence: true, length: { maximum: 140, minimum: 1 }
end

我正在考虑使用单表继承,如下所示:

class Image < Gallery
end

class Link < Gallery
end

class Video < Gallery
end

class Text < Gallery
end

但我没有达到我想要的结果。首先,我想使用Gallery控制器中的方法,例如:

# galleries_controller.rb
def like 
    @gallery = Gallery.find(params[:id])
    @like = @gallery.likes.build(:user_id => current_user.id)
    respond_to do |format|
        if @like.save
        format.html { redirect_to @gallery }
        format.js
    end
end

此外,我想创建一个“发布商”表单,其中包含每种帖子类型的表单,并允许您创建任何类型的帖子。

你会怎么做?我是Rails的新手,我想利用它提供的所有便利。非常感谢!

2 个答案:

答案 0 :(得分:0)

我会将Gallery设为一个抽象类,每个子类都有一个单独的数据库表。这将允许子类具有唯一属性以及共享属性。

class Gallery < ActiveRecord::Base
  self.abstract_class = true # very important
  .
  .
end

我会让画廊控制器变成多态:

class GalleriessController < ApplicationController
  before_filter :find_gallery

  private

  def find_gallery
    @klass = params[:gallery_type].capitalize.constantize
    @gallery = @klass.find(params[:gallery_id])
  end
end

<强>查看:

您可以使用form_for @gallery,但需要进行一些按摩才能使用上面的多态控制器。它需要提交一个gallery_type和gallery_id参数,而不仅仅是一个id。您可以修改form_for的:url param来执行此操作或使用hidden_​​fields。 在form_for中你可以使用partials,每个子类一个。

<强>路线:

您可以像这样定义常规资源:resources:gallery 但是,您需要将id参数设为gallery_id(并且始终传递galley_type参数)。检查一下:Changing the id parameter in Rails routing

(可能)结论

有时花哨的多态性东西会很好用,但在其他情况下,更简单的暴力方法可能更好:每个子类都有一个控制器。这取决于实际情况。 如果你最终做了太多的东西,Rails框架没有给你免费,也许最好考虑另一种方法。

答案 1 :(得分:0)

我有一个类似的场景,在寻找一种很好的实现方式之后,我发现了我正在使用的这个宝石:

https://github.com/hzamani/acts_as_relation

它使用多态has_one关联来模拟多表继承,因此在您的情况下,您可以执行以下操作:

class Gallery < ActiveRecord::Base
  acts_as_superclass
  ...
end

class Image < ActiveRecord::Base
  acts_as :gallery
  ...
end

class Link < ActiveRecord::Base
  acts_as :gallery
  ...
end

我希望这会对你有所帮助。 干杯!