Rails 3多态关联与Paperclip和多个模型

7

我希望使用Paperclip实现多态关联,允许用户拥有一个头像和多个图片。

附件 模型:

class Attachment < ActiveRecord::Base
belongs_to :attachable, :polymorphic => true
end

class Avatar < Attachment
has_attached_file :image, :styles => { :thumb => "150x150>", :view => "260x180>" },
end

class Image < Attachment
has_attached_file :image, :styles => { :thumb => "150x150>", :view => "260x180>" },
end

用户模型:

has_one :avatar, :as => :attachable, :class_name => 'Attachment', :conditions => {:type => 'avatar'}
accepts_nested_attributes_for :avatar

用户控制器:

def edit
   @user.build_avatar
end

用户查看表单:

<%= form_for @user, :html => { :multipart => true } do |f| %>

  <%= f.fields_for :avatar do |asset| %>
      <% if asset.object.new_record? %>
          <%= asset.file_field :image %>
      <% end %>
  <% end %>

当我试图保存更改时,出现错误 => 未知属性:avatar。
如果我在has_one关联中删除:class_name =>'attachment',则会出现错误 => 未初始化常量User :: Avatar。
我还需要将头像附加到博客文章中,因此我需要关联成为多态(或者至少我认为如此)。
我被卡住了,任何帮助都将不胜感激。
2个回答

7

我正在进行一项成功使用Paperclip和多态关联的IT技术项目。让我向您展示我的项目,或许您可以将其应用于您的项目:

class Song < ActiveRecord::Base
  ...
  has_one :artwork, :as => :artable, :dependent => :destroy
  accepts_nested_attributes_for :artwork
  ...
end

class Album < ActiveRecord::Base
  ...
  has_one :artwork, :as => :artable, :dependent => :destroy
  accepts_nested_attributes_for :artwork
  ...
end

class Artwork < ActiveRecord::Base
  belongs_to :artable, :polymorphic => true
  attr_accessible :artwork_content_type, :artwork_file_name, :artwork_file_size, :artwork

  # Paperclip
  has_attached_file :artwork,
    :styles => {
      :small => "100",
      :full => "400"
    }

  validates_attachment_content_type :artwork, :content_type => 'image/jpeg'
end

歌曲和专辑表格都包含了这个部分:
<div class="field">
<%= f.fields_for :artwork do |artwork_fields| %>
  <%= artwork_fields.label :artwork %><br />
  <%= artwork_fields.file_field :artwork %>
<% end %>

不要忘记在表单中包含 :html => { :multipart => true }。
artworks_controller.rb
class ArtworksController < ApplicationController
  def create
    @artwork = Artwork.new(params[:artwork])

    if @artwork.save
        redirect_to @artwork.artable, notice: 'Artwork was successfully created.'
    else
        redirect_to @artwork.artable, notice: 'An error ocurred.'
    end
  end
end

最后,来自songs_controller.rb的一段节选:

def new
    @song = Song.new
    @song.build_artwork
end

@kaigth,抱歉让你费了这么大劲。我本应该从一开始就这样做的。祝一切顺利。 - Brett
艺术品模型中的附件样式是否可以根据多态关系在专辑和歌曲上有所不同? - ramkumar
@RamkumarMK 我相信你的模型都会共享相同的艺术风格。因此,在一个位置上,你应该定义所有模型需要的样式,否则请重新考虑是否需要使用多态关联,而不是针对每种情况使用独特的东西。 - Brett
@Brett 在我的情况下,不同的模型需要有不同的艺术风格。这篇文章推荐使用 STI 和多态组合解决方案,这解决了我的问题。 - ramkumar

0

我不确定你真的需要 polymorphic。这种方法怎么样,它使用了 has_many: through?简单来说,用户有一个头像,它有多个图片,通过这种关联,你可以调用 User.images来获取与头像相关联的图片集合。

http://guides.rubyonrails.org/association_basics.html

class User < ActiveRecord::Base
  has_one :avatar
  has_many :images, :through => :avatar
end

class Avatar < ActiveRecord::Base
  belongs_to :user
  has_many :images
end

class Image < ActiveRecord::Base
  belongs_to :avatar
  has_attached_file :image, :styles => { :thumb => "150x150>", :view => "260x180>" },
end

说了这么多,我不禁想知道为什么你需要这样做。为什么不直接

class User < ActiveRecord::Base
  has_many :avatars
end

这将为您提供任意数量的图片(头像)。


太棒了,但我还想将头像附加到博客文章中,所以我仍然需要使用多态关联Post :: Avatar。 - kaigth
@kaigth,您不想将用户附加到博客文章中,并获取他们关联的头像吗? - Brett
@ Brett 我希望用户能够为博客文章分配单独的头像,这样他们的文章可以独特,而不是使用用户头像。 - kaigth
另外,我稍后会向其他模型添加图像,这就是为什么我需要它是多态的原因。 - kaigth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接