Mój stary formularz:
_form.html.erb
<%= simple_form_for [:user, @product] do |f| %>
<%= f.input :name, label: "Nazwa" %>
<%= f.input :description, label: "Opis" %>
<%= f.input :long_description, label: "Długi opis" %>
<%= f.input :price, label: "Cena" %>
<%= f.association :category, label: "Kategoria" %>
<%= f.input :condition, label: "Stan", :collection => [['Nowy','Nowy'],['Używany','Używany']] %>
<%= f.file_field :photo, :class => "dropzone", multiple: true %>
<%#= f.submit "Dodaj", :class => "btn btn-success" %>
<%# end %>
product.rb
class Product < ActiveRecord::Base
mount_uploaders :photo, ProductPhotoUploader
serialize :photo, JSON
end
products_controller.rb
class User::ProductsController < User::BaseController
before_action :edit, only: [:show, :edit, :update, :destroy, :product_owner]
#before_action :authenticate_user!,except:[:index]
before_action :authenticate_user!
before_action :product_owner, only: [:edit, :update, :destroy]
#skip_before_action :verify_authenticity_token
def product_owner
unless @product.user_id == current_user.id
flash[:danger] = 'Odmowa dostępu, nie jesteś właścicielem tego produktu!'
redirect_to user_root_path
end
end
def index
@q = Product.where(user_id: current_user).ransack(params[:q])
#@q = Product.ransack(params[:q])
@products = @q.result(distinct: true).page(params[:page]).per(30)
end
def new
@product = Product.new
end
def create
@product = Product.new(product_params)
@product.user_id = current_user.id
if @product.save
redirect_to user_products_path, notice: "Pomyślnie dodano produkt."
else
render action: :new
end
end
def edit
@product = Product.find(params[:id])
end
def update
@product = Product.find(params[:id])
if @product.update_attributes(product_params)
redirect_to user_products_path, notice: "Pomyślnie zaktualizowano produkt"
else
render action: :edit
end
end
def destroy
@product = Product.find(params[:id])
@product.destroy
redirect_to user_products_path, notice: "Pomyślnie usunięto produkt"
end
private
def product_params
params.require(:product).permit(
:name,
:category_id,
:description,
:long_description,
:price,
{photo: []},
:condition
)
end
end
Działał bez zarzutu ale chciałem dorzucić pare rzeczy takie jak podgląd, drag’n drop itp.
Korzystam z tego gem’a dropzonejs-rails
widok:
<%= simple_form_for [:user, @product], html: {id: "dropzone-form-id"} do |f| %>
<%= f.input :name, label: "Nazwa" %>
<%= f.input :description, label: "Opis" %>
<%= f.input :long_description, label: "Długi opis" %>
<%= f.input :price, label: "Cena" %>
<%= f.association :category, label: "Kategoria" %>
<%= f.input :condition, label: "Stan", :collection => [['Nowy','Nowy'],['Używany','Używany']] %>
<div id="files-field"
class="dropzone"
style="border: 2px dashed rgba(0, 0, 0, 0.3);
min-height: 100px !important;">
<div class="dz-message"
style="margin: 20px">
Drag your cats' pics here! Or
<button>
select files
</button>
</div>
</div>
<p>
<%= f.submit %>
</p>
<% end %>
upload-dropzone.js
// .js file
Dropzone.options.filesField = {
url: "/user/products",
addRemoveLinks: true,
autoProcessQueue: false,
uploadMultiple: true,
accept: function(file, done) {
$("div#files-field").css({"height": "auto"});
done();
},
init: function() {
var myDropzone = this;
var form = document.getElementById('dropzone-form-id');
form.addEventListener('submit', function(event) {
// stop the form's submit event
if(myDropzone.getQueuedFiles().length > 0){
event.preventDefault();
event.stopPropagation();
myDropzone.processQueue();
}
});
myDropzone.on("sendingmultiple", function(file, xhr, formData) {
formData.append("name", $('#product_name').val());
formData.append("description", $('#product_description').val());
formData.append("long_description", $('#product_long_description').val());
formData.append("price", $('#product_price').val());
formData.append("category", $('#product_category_id').val());
formData.append("condition", $('#product_condition').val());
});
},
successmultiple: function(data,response) {
alert(response);
}
};
bez dodania linijki skip_before_action :verify_authenticity_token
w kontrolerze wyskakuje błąd
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
po dodaniu wyskakuje
Started POST "/user/products" for 127.0.0.1 at 2019-07-30 15:29:27 +0200
Processing by User::ProductsController#create as JSON
Parameters: {"name"=>"", "description"=>"", "long_description"=>"", "price"=>"", "category"=>"",
"condition"=>"", "file"=>{"0"=>#<ActionDispatch::Http::UploadedFile:0x00007fbe12aa45d8 @tempfile=#
<Tempfile:/tmp/RackMultipart20190730-32614-658ixz.png>, @original_filename="Zrzut ekranu z 2019-03-
05 11-37-48.png", @content_type="image/png", @headers="Content-Disposition: form-data;
name=\"file[0]\"; filename=\"Zrzut ekranu z 2019-03-05 11-37-48.png\"\r\nContent-Type: image/png\r\n">}}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC
LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/dondaro/.rvm/gems/ruby-2.5.3/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98
Completed 400 Bad Request in 2ms (ActiveRecord: 0.2ms)
ActionController::ParameterMissing (param is missing or the value is empty: product):
app/controllers/user/products_controller.rb:60:in `product_params'
app/controllers/user/products_controller.rb:27:in `create'
z tego co widzę to jest generowany parametr “file” zamiast “photo” jak mam go zmienić? czy może lepiej go nie zmieniać? co mam zrobić żeby to działało? i jak nie pomijać weryfikacji tokena?