2016-12-14 6 views
0

Ich habe Produkt Modell mit einigen Parametern (Preis, category_id, Bild usw.).Rails Objekt verliert Wert während der Erstellung

Beim Erstellen eines neuen Produkts in der Form teilweise, Kategorie wird über select_tag ausgewählt und Bild wird über Carrierwave hochgeladen, Bild-Uploader. Schlechte Dinge passieren, wenn ich dem Benutzer das hochgeladene Bild in der Datei crop.html.erb zuschneide. Dort crops image, clicks submit, der Pfad als Update verwendet (nicht sehr sicher, welches HTTP-Protokoll), und wird in Product Edit-Seite umgeleitet, da Produkt irgendwie verloren category_id Parameter. Das Formular zeigt einen Fehler bei der Auswahl einer Kategorie an (alle anderen Parameter aus Eingabefeldern gehen nicht verloren).

Meine Versuche war wie die crop Methode definiert, und Kategorie gibt Einstellung, aber kein Glück ...

products_controller.rb:

def edit 
    @categories = Category.all 
    end 

    def create 
    @product = Product.new(product_params) 
    @product.category_id = params[:category_id] 
    @product.user_id = current_user.id 

    respond_to do |format| 
     if @product.save 
     if params[:product][:image].present? 
      format.html { render :crop } 
     else 
      format.html { redirect_to @product, notice: 'Product was successfully created.' } 
      format.json { render :show, status: :created, location: @product } 
     end 
     else 
     format.html { render :new } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    def update 
    @product.category_id = params[:category_id] 

    respond_to do |format| 
     if @product.update(product_params) 
     if params[:product][:image].present? 
      format.html { render :crop } 
     else 
      format.html { redirect_to @product, notice: 'Product was successfully updated.' } 
      format.json { render :show, status: :ok, location: @product } 

      @products = Product.all 
      ActionCable.server.broadcast 'products', 
      html: render_to_string('store/index', layout: false) 
     end 
     else 
     format.html { render :edit } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

crop.html.erb (in Produkte Ordner):

<%= image_tag @product.image_url(:large), id: "cropbox" %> 

<h4>Preview</h4> 
<div style="width:300px; height:200px; overflow:hidden;"> 
    <%= image_tag @product.image.url(:large), :id => "preview" %> 
</div> 

<%= form_for @product do |f| %> 
    <% %w[x y w h].each do |attribute| %> 
    <%= f.hidden_field "crop_#{attribute}" %> 
    <% end %> 
    <div class="actions"> 
    <%= f.submit "Crop" %> 
    </div> 
<% end %> 

Ich habe nicht versucht, einen Rückruf zu setzen, der category_id speichert, aber ich frage mich, wäre es eine gute Idee? Irgendeine Hilfe? Vielen Dank!

EDIT - auch eine Form teilweise Zugabe, aber es funktioniert gut - nur für Ihre Neugier:

<%= form_for(product, hmtl: { multipart: true }) do |f| %> 
... 
    <div class="field"> 
    <%= f.label :category %> 
    <%= select_tag(:category_id, options_from_collection_for_select(Category.all, :id, :name, @product.category_id), include_blank: "Select Category") %> 
    </div> 

UPDATE

Logs für diese Aktionen:

Started GET "/products/new" for ::1 at 2016-12-15 09:03:31 +0200 
Processing by ProductsController#new as HTML 
    [1m[36mCart Load (0.4ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mUser Load (2.0ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]] 
    Rendering products/new.html.erb within layouts/application 
    [1m[36mCategory Load (0.4ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m 
    Rendered products/_form.html.erb (6.2ms) 
    Rendered products/new.html.erb within layouts/application (11.2ms) 
    [1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m 
    [1m[36mLineItem Load (0.5ms)[0m [1m[34mSELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = $1[0m [["cart_id", 5]] 
Completed 200 OK in 127ms (Views: 113.2ms | ActiveRecord: 3.3ms) 


Started POST "/products" for ::1 at 2016-12-15 09:03:40 +0200 
Processing by ProductsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"eWZuqL6AqcN8wknjEL115ax9uBnpY4b9eP0o2xN2aPntd61YKyc4Ym1lUgjV1YrXfZbPr57HANXy7Kz5swCtlg==", "product"=>{"title"=>"kj", "description"=>"kj", "image"=>#<ActionDispatch::Http::UploadedFile:0x007fe40ba4abe0 @tempfile=#<Tempfile:/var/folders/dn/zq9x2jkd4856kwhfj5gbz2tc0000gn/T/RackMultipart20161215-3987-1adfacs.png>, @original_filename="Screen Shot 2016-12-05 at 09.14.48.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"product[image]\"; filename=\"Screen Shot 2016-12-05 at 09.14.48.png\"\r\nContent-Type: image/png\r\n">, "price"=>"98", "quantity"=>"98"}, "category_id"=>"1", "commit"=>"Create Product"} 
    [1m[36mCart Load (0.3ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mUser Load (0.7ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]] 
    [1m[35m (0.3ms)[0m [1m[35mBEGIN[0m 
    [1m[36mCategory Load (0.3ms)[0m [1m[34mSELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 LIMIT $2[0m [["id", 1], ["LIMIT", 1]] 
    [1m[35mSQL (1.0ms)[0m [1m[32mINSERT INTO "products" ("title", "description", "price", "quantity", "created_at", "updated_at", "category_id", "user_id", "image") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"[0m [["title", "kj"], ["description", "kj"], ["price", #<BigDecimal:7fe40ccf9110,'0.98E2',9(18)>], ["quantity", 98], ["created_at", 2016-12-15 07:03:41 UTC], ["updated_at", 2016-12-15 07:03:41 UTC], ["category_id", "1"], ["user_id", 1], ["image", "Screen_Shot_2016-12-05_at_09.14.48.png"]] 
    [1m[35m (3.1ms)[0m [1m[35mCOMMIT[0m 
    Rendering products/crop.html.erb within layouts/application 
    Rendered products/crop.html.erb within layouts/application (3.1ms) 
    [1m[36mCategory Load (0.7ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m 
    [1m[36mLineItem Load (0.3ms)[0m [1m[34mSELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = $1[0m [["cart_id", 5]] 
Completed 200 OK in 957ms (Views: 127.8ms | ActiveRecord: 6.7ms) 

Also ich bemerkte, dass es products/crop.html.erb ohne eine bestimmte ID rendert, so fügte ich meine Routen hinzu:

resources :products do 
    get 'crop', on: :member 
    end 

Und products_controller erstellen Aktion:

... 
    respond_to do |format| 
     if @product.save 
     if params[:product][:image].present? 
      format.html { render crop_product_path(@product) } 
     else 
... 

Immer noch die gleichen Fehler, dass eine Kategorie ausgewählt werden müssen. Und beachten - falls einfach gehen Produkt zu bearbeiten (aber nicht von der crop Aktion), Kategorie dasitzt wie soll ...

+0

Versuchen Zusatz 'hidden_field' für' category_id' in Ihrem 'crop.html' erhalten Aussicht. und setze es auf '@ product.category_id'. Dann können Sie später den Wert in 'update' Aktion – Kkulikovskis

+0

Hm, schönen Fang, aber dann bekomme ich' undefined Methode {: category_id => "1"} ''... Versucht, Produkt in Crop-Aktion im Produkt-Controller zu definieren. .. Verstecktes Feld: '<% = f.hidden_field: category_id => @ product.category_id%>' –

+1

Wenn Sie das versteckte Feld in das Formular einfügen, wird es unter 'product' gesetzt, um die Kategorie_ID in der Update-Aktion zu erhalten unter 'params [: product] [: category_id]' – Kkulikovskis

Antwort

1

Da nur Form die Parameter einreicht gesammelt, die in ihm definiert sind, sollten Sie hinzufügen, ein versteckt Feld die category_id in crop.html Ansicht festlegen

<%= image_tag @product.image_url(:large), id: "cropbox" %> 

<h4>Preview</h4> 
<div style="width:300px; height:200px; overflow:hidden;"> 
    <%= image_tag @product.image.url(:large), :id => "preview" %> 
</div> 

<%= form_for @product do |f| %> 
    <% %w[x y w h].each do |attribute| %> 
    <%= f.hidden_field "crop_#{attribute}" %> 
    <% end %> 
    <%= f.hidden_field :category_id %> 
    <div class="actions"> 
    <%= f.submit "Crop" %> 
    </div> 
<% end %> 

Nun, wenn Sie das Formular aus, Sie category_id auf Server in params[:product][:category_id]

Verwandte Themen