i am creating a form where you can upload the image file, but whenever i submit the form, it dosent permit the image and in the terminal it shows "Unpermitted parameter: :image. Context: { controller: InstrumentsController, action: update, request: #ActionDispatch::Request:0x00007f1955b24b50, params: {"_me................."
also if i check using the rails console if the image is being uploaded or not by typing the Instrument.all (Instrument is a table in database), it shows that it is nil,
i have permitted the :image in params
instruments_controller.rb
class InstrumentsController < ApplicationController
before_action :set_instrument, only: %i[ show edit update destroy ]
before_action :authenticate_user!, except: [:index, :show]
# GET /instruments or /instruments.json
def index
@instruments = Instrument.all.order("created_at desc")
end
# GET /instruments/1 or /instruments/1.json
def show
end
# GET /instruments/new
def new
@instrument = current_user.instruments.build
end
# GET /instruments/1/edit
def edit
end
# POST /instruments or /instruments.json
def create
@instrument = current_user.instruments.build(instrument_params)
respond_to do |format|
if @instrument.save
format.html { redirect_to instrument_url(@instrument), notice: "Instrument was successfully created." }
format.json { render :show, status: :created, location: @instrument }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @instrument.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /instruments/1 or /instruments/1.json
def update
respond_to do |format|
if @instrument.update(instrument_params)
format.html { redirect_to instrument_url(@instrument), notice: "Instrument was successfully updated." }
format.json { render :show, status: :ok, location: @instrument }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @instrument.errors, status: :unprocessable_entity }
end
end
end
# DELETE /instruments/1 or /instruments/1.json
def destroy
@instrument.destroy
respond_to do |format|
format.html { redirect_to instruments_url, notice: "Instrument was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_instrument
@instrument = Instrument.find(params[:id])
end
# Only allow a list of trusted parameters through.
def instrument_params
params.require(:instrument).permit(:brand, :model, :description, :condition, :finish, :tiitle, :price, :image)
end
end
and inside the model (ignore 'tiitle' as i have already done a typo and continue to use it instead of 'title')
instrument.rb
class Instrument < ApplicationRecord
mount_uploader :image, ImageUploader
belongs_to :user, optional: true
validates :tiitle, :brand, :price, :model, presence: true
validates :description, length: { maximum: 1000, too_long: "%{count} is the maximum allowed characters" }
validates :tiitle, length: { maximum: 140, too_long: "%{count} is the maximum allowed characters" }
validates :price, numericality: { only_integer: true }, length: { maximum: 7 }
BRAND = %w{ Fender Gibson Epiphone ESP Martin Dean Taylor Jackson PRS Ibanez Charvel Washburn }
FINISH = %w{ Black White Navy Blue Red Clear Satin Yellow Seafoam }
CONDITION = %w{ New Excellent Mint Used Fair Poor }
end
_form.html.erb
<%= simple_form_for @instrument, html: { multipart: true } do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<div class="form-inputs">
<div class="row ">
<div class="col mx-auto">
<div class="card mt-2 mx-auto p-4 bg-light">
<div class="card-body bg-light">
<div class = "container">
<div class="controls">
<div class="row">
<div class="col-md-10">
<div class="form-group">
<%= f.input :tiitle, input_html: {class: "form-control"} %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<%= f.input :model, input_html: {class: "form-control"} %>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<%= f.input :price %>
</div>
</div>
</div>
</div>
</div>
<%= f.input :description %>
<%= f.label :condition %>
<div class="row">
<div class="col-sm-1">
<div class="form-group">
<%= f.input_field :condition, collection: Instrument::CONDITION, prompt: "Select Condition" %>
</div>
</div>
</div>
<%= f.label :brand %>
<div class="row">
<div class="col-sm-1">
<div class="form-group">
<%= f.input_field :brand, collection: Instrument::BRAND, prompt: "Select Brand" %>
</div>
</div>
</div>
<%= f.label :finish %>
<div class="row">
<div class="col-sm-1">
<div class="form-group">
<%= f.input_field :finish, collection: Instrument::FINISH, prompt: "Select Finish" %>
</div>
</div>
</div>
<%= f.input :image, as: :file, input_html:{ multiple: true, class:"file-input instrument-image" }, label: false, wrapper: false %>
</div>
</div>
</div>
</div>
</div>
<div class="form-actions">
<div class="row">
<div class="col-sm-1">
<%= f.button :submit, "Create instrument", class: "btn btn-success create-instrument-btn" %>
</div>
<div class="col-sm-2">
<%= link_to "Cancel", instruments_path, class: "btn btn-danger cancel-instrument-btn" %>
</div>
</div>
</div>
<% end %>
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
version :thumb do
process resize_to_fit: [400, 300]
end
version :default do
process resize_to_fit: [800, 600]
end
# Add an allowlist of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_allowlist
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
i am a newbie, according to the knowledge what i have understood is that we have to use html: {multipart: true} in the form initializing so that it accepts the uploader as file and permit the ':image' in controller's file and it should work but when i click the "Create" button, it dosen't upload the image and shows unpermitted params in terminal while i submit it and creates a new instrument with all fields except the uploader. Any fixes? :')