2009-05-07 8 views
1

Ich komme auf Schienen auf Hochtouren und geriet in ein seltsames Problem. Ich rendere einige Bilder aus der Datenbank (Bildmodelle an ein anderes Modell, Pflanzen). Ich habe einige Probleme, wenn ich versuche, es über eine partielle zu tun. Ich habeRails Partial Image Rendering

<fieldset class="fieldset"> 
     <legend>Images</legend> 
     <%= unless @plant.images.blank? then 
       for image in @plant.images 
        debugger 
        render :partial => 'show_image', :object => image 
       end 
      else 
       "This plant has no images to display." 
      end 
     %> 
</fieldset> 

und der Teil _show_image.html.erb show.html.erb bekommt:

<div class="image_container"> 
     <% debugger %> 
     <img src="<%= url_for(:action => 'picture', :id => object.id) %>"/> 
     <p class='image_caption'><%= object.comment %></p> 
</div> 

Wenn dies gemacht wird, es macht nur einen „#“ für jedes Bild, anstatt der tatsächliches Bild Es scheint nur zu sein, das Objekt als String-Rendering, wie es in der Quelle erhalte ich:

<fieldset class="fieldset"> 
     <legend>Images</legend> 
     #<Image:0x242c910> 
</fieldset> 

Wenn lokal über den Debugger ausgeführt wird:

/Users/*****/dev/plantmanager/app/views/plants/show.html.erb:54 
debugger 
(rdb:241) image 
#<Image id: 40, comment: "Test", name: "Ixia.gif", content_type: "image/gif", data: "GIF89a2\0002\000####$\205\233\tI\250\"x\224\b?\206\031d|ju####\v\031###\247\bI\257G\222\232\222\227\263\262...", plant_id: 55, thumbnail: nil> 
(rdb:221) @plant 
#<Plant id: 55, name: "Test", description: "Test", created_at: "2009-05-07 07:19:44", updated_at: "2009-05-07 07:19:44", planted: "2009-05-07 00:00:00", sprouted: "2009-05-15 00:00:00", plant_type_id: 1, finished: "2009-05-27 00:00:00"> 
(rdb:221) @plant.images 
[#<Image id: 40, comment: "Test", name: "Ixia.gif", content_type: "image/gif", data: "GIF89a2\0002\000####$\205\233\tI\250\"x\224\b?\206\031d|ju####\v\031###\247\bI\257G\222\232\222\227\263\262...", plant_id: 55, thumbnail: nil>] 
(rdb:221) continue 
/Users/*****/dev/plantmanager/app/views/plants/_show_image.html.erb:2 
<% debugger %> 
(rdb:221) object 
#<Image id: 40, comment: "Test", name: "Ixia.gif", content_type: "image/gif", data: "GIF89a2\0002\000####$\205\233\tI\250\"x\224\b?\206\031d|ju####\v\031###\247\bI\257G\222\232\222\227\263\262...", plant_id: 55, thumbnail: nil> 
(rdb:221) object.id 
40 
(rdb:221) object.comment 
"Test" 
(rdb:221) continue 

Hier meine Modelle sind [snipped ein bisschen]:

class Plant < ActiveRecord::Base 
    has_many :images 

    validates_presence_of :name 
    validates_presence_of :plant_type_id 
    validates_associated :images 


    after_update :save_images 

    def image_attributes=(image_attributes) 
      image_attributes.each do |attributes| 
       # TODO: Probably handle validation in the image model? 
       if attributes[:id].blank? 
        unless attributes[:uploaded_picture].blank? 
         tmpImg = images.build() 
         tmpImg.uploaded_picture=attributes[:uploaded_picture] 
         tmpImg.comment = attributes[:comment] 
        end 
       else 
        img = images.detect { |i| i.id == attributes[:id].to_i } 
        img.attributes = attributes 
       end 
      end 
     end 


     def save_images 
      images.each do |i| 
       if i.should_destroy? 
        i.destroy 
       else 
        i.save(false) 
       end 
      end 
     end 
end 

class Image < ActiveRecord::Base 
     validates_format_of :content_type, 
          :with => /^image/, 
          :message => "--- you can only upload pictures" 

     attr_accessor :should_destroy 

     def should_destroy? 
      should_destroy.to_i == 1 
     end 

     def uploaded_picture=(picture_field) 
      self.name = base_part_of(picture_field.original_filename) 
      self.content_type = picture_field.content_type.chomp 
      self.data = picture_field.read 
      #image = MiniMagick::Image.from_blob self.data 
      #self.thumbnail = resize_and_crop(image, 100).to_blob 
     end 

     def base_part_of(file_name) 
      File.basename(file_name).gsub(/[^\w._-]/, '') 
     end 
end 

Antwort

4

Versuchen Sie stattdessen:

<% unless @plant.images.blank? 
       for image in @plant.images 
%> 
        <%= render :partial => 'show_image', :object => image %> 
       <% end 
      else %> 
       This plant has no images to display. 
      <% end %> 

Sorry wegen der Formatierung, aber Sie bekommen die Idee.

+0

Danke, das hat perfekt funktioniert. Ich werde den Dreh dieser Syntax irgendwann bekommen ... =) –

+0

Der Trick ist, <% = vor 'render' Aufruf zu erzwingen. –

1

ein Verfahren beim Aufbau für das Bild im Bild eines Modell

class Image < ActiveRecord::Base 
    belongs_to :plant 
    validates_presence_of :uploaded_picture 
    ... 
end 

In Ihren Pflanzen Controller

def plant_pic 
    img = Image.find(params[:id])  
    # THE NEXT LINE IS THE ONE I THINK YOU ARE MISSING: 
    send_data img.uploaded_picture, :filename =>"plant#{img.plant_id}_#{img.id.to_s}+'.jpg', 
            :type => 'image/jpeg', 
            :disposition => 'inline' 
end 
... 

Und dann in Ihren Pflanzen sehen:

<fieldset class="fieldset"> 
    <legend>Images</legend> 
    <% if plant.images.blank? -%> 
    <p>This plant has no images to display.</p> 
    <% else %> 
    <%= @plant.images.each do |image| %> 
     <div class="img_container"> 
     <img src="<%= url_for(:action => 'plant_pic', :id => image.id) %>"/> 
     </div> 
    <% end -%> 
    <% end -%> 
</fieldset> 

Sie können wollen, kodiere/dekodiere das uploaded_picture Binär-Feld irgendwie (ich benutze Base64.encode und Base64.decode) in deinen images contr oller, aber das ist ein anderes Problem.

Hoffe das hilft dir

+0

Bild (binäre) Daten von Ruby-Domain senden ist keine gute Idee - Delegieren Sie den Core-Web-Server, um das zu tun - sie werden viel mehr optimale Arbeit tun. Ich meine, das Überlegen von Bildern auf separate, statisch-content Web-Server. –