Topic: attachment_fu, polymorphic model - help please...

First of all, apologies, as I am probably missing something utterly obvious.

I am trying to set up a polymorphic assets model, with attachment_fu. Essentially attachment_fu is working as I can upload directly to the attachment model. However when I try and upload a file from another controller (linked polymorphically) I get errors about the content_type etc. not being in the list.

I assume this means that the params array isn't capturing the data? How can I correct this?
in my asset model i have:

belongs_to :attachable, :polymorphic => true

(and has_attachment + validates_as_attachment)

in my product model I have:

  has_many :assets, :as => :attachable

in the create method in my products controller is am using:
@asset = @product.assets.build(params[:uploaded_data])

In my new product form I have:
<%= file_field 'asset', 'uploaded_data'  %>

A yaml dump of the form content
--- !map:HashWithIndifferentAccess html: multiparttrue commit: Create product: !map:HashWithIndifferentAccess name: test body: test title: test green: test category_ids: - "3" sidebar: "" description: test action: create controller: admin/products asset: !map:HashWithIndifferentAccess uploaded_data: cm_logo.jpg

The errors I get:
Assets is invalid
Content type is not included in the list
Content type can't be blank
Size is not included in the list
Size can't be blank
Filename can't be blank

Any help greatly appreciated.

Re: attachment_fu, polymorphic model - help please...

Having the same problem. I'm losing the uploaded_data when I add it to a different form/controller. Any luck solving this problem?

Re: attachment_fu, polymorphic model - help please...

Hi, sorry it took so long to reply, I've been away.

The solution was:
@asset = @product.assets.build(params[:asset])

not:
asset = @product.assets.build(params[:uploaded_data])

Doh!

I know it's a late responce, but I hope that helps.

Re: attachment_fu, polymorphic model - help please...

Hi Spencer,

Thanks for the response. I tried your solution, but I'm getting an error.

undefined method `content_type' for "myImage.gif":String

RAILS_ROOT: script/../config/..
Application Trace | Framework Trace | Full Trace

vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu.rb:255:in `uploaded_data='
vendor/rails/activerecord/lib/active_record/base.rb:1673:in `send'
vendor/rails/activerecord/lib/active_record/base.rb:1673:in `attributes='
vendor/rails/activerecord/lib/active_record/base.rb:1672:in `each'
vendor/rails/activerecord/lib/active_record/base.rb:1672:in `attributes='
vendor/rails/activerecord/lib/active_record/base.rb:1506:in `initialize_without_callbacks'
vendor/rails/activerecord/lib/active_record/callbacks.rb:225:in `initialize'
vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb:13:in `new'
vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb:13:in `build'
app/controllers/events_controller.rb:36:in `create'

Appreciate your help!

Re: attachment_fu, polymorphic model - help please...

"undefined method `content_type' for "myImage.gif":String"

that looks like your form isn't working as multipart, but, I am by no means an expert...

N.B. - I am not using a has_many, now has_one. (however, hopefully this'll still help) I did also have this working with has_many, although you have to use assets.build to get that hooked up...there are other posts here that cover it.

What I have now:
Products Controller:

def new
    @asset = Asset.new
    @product = Product.new
  end
 
  def create
    @product = Product.new(params[:product])
    @asset = Asset.new(params[:asset])
    @product.asset = @asset
    if @product.save
      flash[:notice] = 'Product was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end

  def edit
    @product = Product.find(params[:id])
    @asset = @product.asset
  end

  def update
    @product = Product.find(params[:id])
    @product.attributes = params[:product]
    if params[:asset][:uploaded_data].blank?
    else
      @asset = Asset.new(params[:asset])
      @product.asset = @asset
    end
    if @product.update_attributes(params[:product])
      flash[:notice] = 'Product was successfully updated.'
      redirect_to :action => 'show', :id => @product.id
    else
      render :action => 'edit'
    end
  end


In my new view: (some "product" related fields stripped out to keep it as clear as possible)
<% form_for :product, :url => { :action => 'create', :id => @product.id }, :html => { :multipart => true } do |f| -%>
      <!--[form:product]-->
      <p><label for="product_title">Title</label><br/>
      <%= f.text_field :title  %></p>
      <p><label for="product_asset">Picture</label><br/>
         <%= file_field 'asset', 'uploaded_data'  %>
<%= submit_tag :Create %>

you can probably also just use
@product

not
@product.id

permalink_fu forced me to do this (probably my bad!)

Product Model:

 has_one :asset, :as => :attachable, :dependent => :destroy

Asset Model: (Storage specifics stripped out
class Asset < ActiveRecord::Base
  belongs_to :attachable, :polymorphic => true, :dependent => :destroy
  has_attachment :storage => :file_system,
    :thumbnails => { :bigthumb => '300>', :thumb => '100>' },
    :max_size => 300.kilobytes
 
  validates_as_attachment
end

P.S. There is probably some nasty code in here. I am newbie!
Anyway that's it. Hope it helps.

Spencer

Re: attachment_fu, polymorphic model - help please...

Thanks Spencer!

I figured out the problem. For some reason you have to use the form_for and not the form_tag. I had everything else exactly as it should be. I'm not exactly sure why you would have to use form_for if asset is technically outside of the main form.

We are good to go now.

Thanks again for your help.
Walksalong

Re: attachment_fu, polymorphic model - help please...

Hi Walksalong.
Excellent news. Glad you cracked it.

Hope I was of some help
Best Regards
Spencer

Re: attachment_fu, polymorphic model - help please...

Ahaa....now I can make it optional on edit:

@product.pictures.build(params[:picture]) unless params[:picture][:uploaded_data].blank?