2016-05-17 4 views
0

Ich habe ein picture Modell, das carrierwave verwendet, um Dateien hochzuladen. Das picture Modell ist eine polymorphe Beziehung mit user Modell und scoreboard Modell. Der gesamte relevante Code ist unten angegeben.Params nicht vorhanden Fehler in den Bildern Modell in Schienen

Die pictureable Controller

class PicturesController < ApplicationController   
    before_filter :load_pictureable 
    before_action :logged_in_user, only: [:create, :update, :destroy] 

    def create 
    @picture = @pictureable.build_picture(picture_params) 
    if @picture.save 
     flash[:success] = "Uploaded Successfully" 
     redirect_to @pictureable 
    else 
     redirect_to @pictureable 
     flash[:danger] = "An error occured, please try again!" 
    end 
    end 

    def update 
    @picture = @pictureable.picture 
    if @picture.update_attributes(picture_params) 
     redirect_to @pictureable 
     flash[:success] = "Picture updated successfully" 
    else 
     redirect_to @pictureable 
     flash[:danger] = "An error occured, please try again!" 
    end 
    end 

    def destroy 
    @pictureable.picture.delete 
    redirect_to @pictureable 
    flash[:success] = "Picture removed successfully" 
    end 

private 

    def picture_params 
    params.require(:picture).permit(:picture) 
    end 

    def load_pictureable 
    resource, id = request.path.split('/')[1,2] 
    @pictureable = resource.singularize.classify.constantize.find(id) 
    end 
end 

Ich benutze HTML5 E-Reader Javascript auf dem vorderen Ende das Bild in einem modalen zu lesen. Die Datei erscheint im Modal gut. Der Javascript-Code ist unten angegeben.

$(document).ready(function(){ 
    var preview = $(".upload-preview img"); 

    $(".hidden").change(function(event){ 
     var input = $(event.currentTarget); 
     var file = input[0].files[0]; 
     var reader = new FileReader(); 
     reader.onload = function(e){ 
      $('#image') 
        .attr('src', e.target.result) 
        .width(307) 
        .height(317); 
      image_base64 = e.target.result; 
      preview.attr("src", image_base64); 
     }; 
     reader.readAsDataURL(file); 
    }); 
}); 

Die Aktion create funktioniert einwandfrei. Jedoch, wenn ich versuche, ein vorhandenes Bild zu aktualisieren, gibt es manchmal gibt mir den folgenden Fehler: param is missing or the value is empty: picture. Der Fehler tritt nur manchmal auf. Ich bin mir nicht sicher, was genau passiert. Ich verstehe, dass der Fehler mir sagt, dass param nicht vorhanden ist.

LOG-Datei für eine UNSUCCESSFUL-Patch-Anfrage.

Started PATCH "/scoreboards/7/pictures/24" for 70.26.106.141 at 2016-05-17 16:27:32 +0000 
Processing by PicturesController#update as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"WoA40xzlc8CH6/gcf6Jd/nqlj/9iOoykcn4H9zAgTkuwi6vAttZEPECYs+OfHZvC3le3nY/sZ/IZSwOL0FhnIQ==", "scoreboard_id"=>"7", "id"=>"24"} 
    [1m[36mScoreboard Load (0.4ms)[0m [1mSELECT "scoreboards".* FROM "scoreboards" WHERE "scoreboards"."id" = $1 ORDER BY "scoreboards"."created_at" DESC LIMIT 1[0m [["id", 7]] 
    [1m[35mUser Load (0.3ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] 
    [1m[36mPicture Load (14.4ms)[0m [1mSELECT "pictures".* FROM "pictures" WHERE "pictures"."pictureable_id" = $1 AND "pictures"."pictureable_type" = $2 LIMIT 1[0m [["pictureable_id", 7], ["pictureable_type", "Scoreboard"]] 
Completed 400 Bad Request in 24ms 

ActionController::ParameterMissing (param is missing or the value is empty: picture): 
    app/controllers/pictures_controller.rb:40:in `picture_params' 
    app/controllers/pictures_controller.rb:20:in `update' 


    Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_source.erb (5.0ms) 
    Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_trace.html.erb (2.3ms) 
    Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_request_and_response.html.erb (1.5ms) 
    Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_web_console.html.erb (1.1ms) 
    Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/diagnostics.html.erb within rescues/layout (110.5ms) 

LOG-Datei für eine erfolgreiche POST-Anfrage

Started POST "/scoreboards/7/pictures" for 70.26.106.141 at 2016-05-17 16:30:00 +0000 
Processing by PicturesController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"jNhAeqUJNZGKEGdDCWSGzGRBSwyXkQIj9iZgMMklqBpm09NpDzoCbU1jLLzp20DwwLNzbnpH6XWdE2RMKV2BcA==", "picture"=>{"picture"=>#<ActionDispatch::Http::UploadedFile:0x00000006c6b7d0 @tempfile=#<Tempfile:/tmp/RackMultipart20160517-27824-1d2x6l4.jpeg>, @original_filename="Home_pic.jpeg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"picture[picture]\"; filename=\"Home_pic.jpeg\"\r\nContent-Type: image/jpeg\r\n">}, "scoreboard_id"=>"7"} 
    [1m[35mScoreboard Load (0.4ms)[0m SELECT "scoreboards".* FROM "scoreboards" WHERE "scoreboards"."id" = $1 ORDER BY "scoreboards"."created_at" DESC LIMIT 1 [["id", 7]] 
    [1m[36mUser Load (0.3ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1[0m [["id", 1]] 
    [1m[35mPicture Load (0.5ms)[0m SELECT "pictures".* FROM "pictures" WHERE "pictures"."pictureable_id" = $1 AND "pictures"."pictureable_type" = $2 LIMIT 1 [["pictureable_id", 7], ["pictureable_type", "Scoreboard"]] 
    [1m[36m (0.2ms)[0m [1mBEGIN[0m 
    [1m[35mSQL (0.7ms)[0m INSERT INTO "pictures" ("picture", "pictureable_id", "pictureable_type", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["picture", "Home_pic.jpeg"], ["pictureable_id", 7], ["pictureable_type", "Scoreboard"], ["created_at", "2016-05-17 16:30:03.046590"], ["updated_at", "2016-05-17 16:30:03.046590"]] 
    [1m[36m (29.2ms)[0m [1mCOMMIT[0m 
Redirected to https://scorecliq-kpauls.c9users.io/scoreboards/7 
Completed 302 Found in 2253ms (ActiveRecord: 31.2ms) 

Die View-Datei in dem modalen gehandhabt wird. Der Code ist unten angegeben. Die editphoto Modal und upload photo Modal sind das Gleiche. Unten ist das EDITPHOTO Modal/UPLOAD PHOTO.

<div> 
    <%= form_for([@pictureable, @picture], html: {multipart: true}) do |f| %> 
    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png', id: "files", class: "hidden" %> 

    <div class="modal fade" id="picmodal" tabindex="-1" role="dialog" aria-labelledby="picmodal" aria-hidden="true"> 
     <div class="modal-dialog"> 
      <div class="modal-content"> 
      <div class="modal-header" style="text-align: center">Selected Image</div> 
      <div class="modal-body"> 
      <div class="upload-preview" style="text-align: center"> 
       <img id="image" /></img> 
      </div> 
      </div> 
      <div class="modal-footer"> 
       <%= f.submit "upload photo", class: "hidden", id: "editphotobutton" %> 
       <button class="btn-s btn-full", for: "editphotobutton">Save Changes</button> 
       <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 
      </div> 
      </div> 
     </div> 
     </div> 
    <% end %> 
</div> 

The View Code, wo ich auf Optionen klicken, um das

Bild zu ändern
<div class="col-xs-12 col-sm-3 score-prof-pic"> 
     <% if @picture.picture.url.present? %> 
      <div class="dropdown"> 
       <%= link_to "#", class: "prof-dropdown" , data: {:toggle => "dropdown"}, role: "button", aria: {:expanded => "false"} do %> 
        <%= image_tag @picture.picture.url, class: "prof-default img-thumbnail" %> 
       <% end %> 
       <% if manager_or_owner?(@scoreboard, current_user) %> 
        <ul class="dropdown-menu"> 
        <li><%= link_to "Upload","#", id: "score-prof-edit" %> </li> 
        <li role="separator" class="divider"></li> 
        <li> <%= link_to "Remove", [@pictureable, @picture], method: :delete, data: {confirm: "Are you sure you want to delete your picture!"} %></li> 
        <li role="separator" class="divider"></li> 
        <li><%= link_to "Cancel", "#" %></li> 
        </ul> 
       <% end %> 
      </div> 
     <% else %> 
      <div class="dropdown"> 
       <%= link_to "#", class: "prof-dropdown" , data: {:toggle => "dropdown"}, role: "button", aria: {:expanded => "false"} do %> 
        <%= image_tag "blank-prof.jpg", class: "prof-default img-thumbnail " %> 
       <% end %> 
       <% if manager_or_owner?(@scoreboard, current_user) %> 
       <ul class="dropdown-menu"> 
        <li><%= link_to "Upload","#", id: "score-prof-upload" %> </li> 
        <li role="separator" class="divider"></li> 
        <li><%= link_to "Cancel", "#" %></li> 
       </ul> 
       <% end %> 
      </div> 
     <% end %> 
    </div> 
+0

@MichaelGaskill, werde ich die Protokoll Datei für Updates veröffentlichen und in der ursprünglichen Frage erstellen. – kpaul

+0

@MichaelGaskill, Die Frage wird mit den Protokolldateien aktualisiert. – kpaul

+0

@MichaelGaskill, ich habe den View-Code gepostet. Das ist so ziemlich alles, was ich früher mit den Bildern gemacht habe. Das JS am Frontend und die Rails am Backend. – kpaul

Antwort

0

Die Schienen starke Parameter für den Controller derzeit erforderlich ist, dass ein neues Bild hochgeladen, wenn der Benutzer das Bildmodell aktualisiert . Dies bedeutet, dass, wenn der Benutzer das Formular absendet, ohne ein neues Bild hochgeladen zu haben, selbst wenn er zuvor erfolgreich ein Bild hochgeladen hat, die starken Parameter die Aktion nicht ausführen.

Um dies zu beheben, ändern Sie die picture_params Methode dazu:

def picture_params 
    params.permit(:picture) 
end 

Diese update ermöglicht, zu arbeiten, selbst wenn der Benutzer eine neue Datei nicht gewählt hat. Im Idealfall würde die Benutzeroberfläche die Schaltfläche Save oder Submit deaktivieren, bis der Benutzer eine Datei zum Hochladen ausgewählt hat, um eine gute Benutzererfahrung zu gewährleisten.

Um sicherzustellen, dass der Benutzer mindestens einmal eine Datei hochgeladen hat, fügen Sie dem Picture-Modell eine Validierung hinzu, um zu bestätigen, dass ein Bild für den Benutzer vorhanden ist. Ohne die spezifischen Details Ihrer Feldnamen zu kennen, Sie so bestätigen können (unter der Annahme, dass :image.

def Picture < ActiveRecord::Base 
    validate :has_picture 

private 

    def has_picture 
    errors.add(:picture, "can't be missing") if !picture.url.present? 
    end 
end 

Dieser Ansatz Ihnen Validierung gibt an Zeit zu sparen, anstatt, wenn die Aktion aufgerufen Dies sollte nicht nur machen Die Aktion ist robuster, aber stellen Sie sicher, dass das Modell immer gültig ist.

+0

Während meine Formulierung für diese Frage falsch war, hast du mir geholfen zu dem Schluss zu kommen, dass das Upload-Formular manchmal keine Dateien akzeptiert. Ich habe versucht, es sichtbar zu machen und es hat viel geantwortet. Während diese Lösung funktioniert, ist es nicht das, wonach ich gesucht habe. Ich muss das Formular selbst reparieren. Meine Frage mag jedoch irreführend sein, deshalb werde ich eine klarere Frage stellen. – kpaul

+0

Hey, ich bin froh, irgendwie geholfen zu haben. Viel Glück! –