0
votes

In rails 3.2 I created a post controller. Each post can have a different number of paperclip attachments. To achieve this I created a assets model where each asset has a paperclip attachment. One post has_many assets and assets belong_to post.

Asset model

class Asset < ActiveRecord::Base
    belongs_to :post
    has_attached_file :photo, :styles => { :thumb => "200x200>" }
end

Post model

 class Post < ActiveRecord::Base
      attr_accessible :content, :title
      has_many :assets, :dependent => :destroy
      validates_associated :assets
      after_update :save_assets

 def new_asset_attributes=(asset_attributes) 
        asset_attributes.each do |attributes| 
            assets.build(attributes) 
        end 
    end
    def existing_asset_attributes=(asset_attributes) 
        assets.reject(&:new_record?).each do |asset| 
        attributes = asset_attributes[asset.id.to_s] 
        if attributes 
            asset.attributes = attributes 
            else 
                asset.delete(asset) 
            end 
        end 
    end

    def save_assets 
        assets.each do |asset| 
            asset.save(false) 
        end 
    end 
end

Posts helper

module PostsHelper
  def add_asset_link(name) 
    link_to_function name do |post| 
      post.insert_html :bottom, :assets, :partial => 'asset', :object => Asset.new 
    end 
  end
end

Form for post

<%= form_for @post, :html => { :multipart => true } do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
        <% @post.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content %>
  </div>
    <div id="assets">
        Attach a file or image<br />
        <%= render 'asset', :collection => @post.assets %> 
      </div> 
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Asset partial

<div class="asset"> 
    <% new_or_existing = asset.new_record? ? 'new' : 'existing' %>
    <% prefix = "post[#{new_or_existing}_asset_attributes][]" %>

    <% fields_for prefix, asset do |asset_form| -%> 
        <p> 
          Asset: <%= asset_form.file_field :photo %> 
          <%= link_to_function "remove", "$(this).up('.asset').remove()" %> 
        </p> 
  <% end -%> 
</div>

Most of the code is taken from here: https://gist.github.com/33011 and I understand this is a rails2 app, anyway I don't understand what this error means:

undefined method `new_record?' for nil:NilClass
Extracted source (around line #2):

1: <div class="asset"> 
2:     <% new_or_existing = asset.new_record? ? 'new' : 'existing' %>
3:     <% prefix = "post[#{new_or_existing}_asset_attributes][]" %>
4:     
5:     <% fields_for prefix, asset do |asset_form| -%> 
2

2 Answers

1
votes

Try changing this

 <div id="assets">
    Attach a file or image<br />
    <%= render 'asset', :collection => @post.assets %> 
  </div>

to

<div id="assets">
  Attach a file or image<br />
  <% @post.assests.each do |asset|%>
    <%= render 'asset', :asset => asset %> 
  <% end %>
</div>

Possible reason is when u calling

<%= render 'asset', :collection => @post.assets %> 

You are passing a collection to the rendered partial but you are no where using ur collection passed by the name collection in the partial. you are using a variable Assest which doesnt exist in scope of that particular rendered partial :)

0
votes

Reading the error, your <%= render 'asset', :collection => @post.assets %> line calls an empty array maybe? In your console, can you find @post.assets and is it nil there?