I am using paperclip gem to upload images but these images are not storing in public folder or anywhere instead it is showing missing.png. I have already specified url, path.
Model - This is the model configured with paperclip
class AudiModel < ActiveRecord::Base
has_attached_file :exterior_image,
:path => ":rails_root/public/system/:attachment/:id/:style/:filename",
:url => "/system/:attachment/:id/:style/:filename",
:styles => { :medium => "300x300>", :thumb => "100x100>" }
validates_attachment_content_type :exterior_image, content_type: /\Aimage\/.*\Z/
end
Contoller
class AudiModelsController < ApplicationController
before_action :set_audi_model, only: [:show, :edit, :update, :destroy]
# GET /audi_models
# GET /audi_models.json
def index
#audi_models = AudiModel.all
end
# GET /audi_models/1
# GET /audi_models/1.json
def show
end
# GET /audi_models/new
def new
#audi_model = AudiModel.new
end
# GET /audi_models/1/edit
def edit
end
# POST /audi_models
# POST /audi_models.json
def create
#audi_model = AudiModel.new(audi_model_params)
respond_to do |format|
if #audi_model.save
format.html { redirect_to #audi_model, notice: 'Audi model was successfully created.' }
format.json { render :show, status: :created, location: #audi_model }
else
format.html { render :new }
format.json { render json: #audi_model.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /audi_models/1
# PATCH/PUT /audi_models/1.json
def update
respond_to do |format|
if #audi_model.update(audi_model_params)
format.html { redirect_to #audi_model, notice: 'Audi model was successfully updated.' }
format.json { render :show, status: :ok, location: #audi_model }
else
format.html { render :edit }
format.json { render json: #audi_model.errors, status: :unprocessable_entity }
end
end
end
# DELETE /audi_models/1
# DELETE /audi_models/1.json
def destroy
#audi_model.destroy
respond_to do |format|
format.html { redirect_to audi_models_url, notice: 'Audi model was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_audi_model
#audi_model = AudiModel.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def audi_model_params
params.require(:audi_model).permit(:car_model, :variant, :introduction, :engine, :exterior_image, :video, :brochure)
end
end
Solved it ! path should be like. Need to specify attributte name also in path.
:path => ":rails_root/public/system/exterior_image/:attachment/:id_partition/:style/:filename"
Related
I wanted to upload image (using paperclip gem) to my product in my rails project, so i watched a youtube video how to do it (https://www.youtube.com/watch?v=Z5W-Y3aROVE) I did all he did, but i when i add a new product i get an error -
'New Product
2 errors prohibited this product from being saved:
Img url Paperclip::Errors::NotIdentifiedByImageMagickError
Img url has contents that are not what they are reported to be' , right above my new product form how do i fix it.
MY PRODUCT MODEL
class Product < ActiveRecord::Base
belongs_to :user
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
has_attached_file :img_url, styles: { large: "800x600>", medium: "320x200>", thumb: "100x80#" }
validates_attachment_content_type :img_url, content_type: /\Aimage\/.*\z/
def self.tagged_with(name)
Tag.find_by!(name: name).products
end
def all_tags=(names)
# names="music, spotify"
self.tags = names.split(',').map do |name|
Tag.where(name: name).first_or_create!
end
end
def all_tags
tags.map(&:name).join(", ")
end
end
MY PRODUCTS_CONTROLLER
class ProductsController < ApplicationController
# before_action :authenticate_user!
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
if params[:tag]
#products = Product.tagged_with(params[:tag])
else
#products = Product.all
end
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = current_user.products.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = current_user.products.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:filetype, :title, :img_url, :description, :all_tags, :price, :uploaded_by, :tutorial_url)
end
end
and i displayed my images as
<%= link_to image_tag(product.img_url.url(:medium), :class =>"img-fluid tm-img"),product%>
relatively new to ruby on rails and I'm creating a simple Uploads model for Paperclip images to be attached and displayed. I've got that all working well, but I want to limit a current user to upload no more than 6 images at any given time.
In what file and what code would I add this? It would be quite helpful to know this for any future model I create !
I'm assuming it's quite a small bit of code but I can't see an answer anywhere online... thanks !
my UploadsController (did a simple scaffolding and paperclip setup):
class UploadsController < ApplicationController
before_action :set_upload, only: [:show, :edit, :update, :destroy]
# GET /uploads
# GET /uploads.json
def index
#uploads = Upload.all
end
# GET /uploads/1
# GET /uploads/1.json
def show
end
# GET /uploads/new
def new
#upload = current_user.uploads.build
end
# GET /uploads/1/edit
def edit
end
# POST /uploads
# POST /uploads.json
def create
#upload = current_user.uploads.build(upload_params)
respond_to do |format|
if #upload.save
format.html { redirect_to #upload, notice: 'Upload was successfully created.' }
format.json { render :show, status: :created, location: #upload }
else
format.html { render :new }
format.json { render json: #upload.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /uploads/1
# PATCH/PUT /uploads/1.json
def update
respond_to do |format|
if #upload.update(upload_params)
format.html { redirect_to #upload, notice: 'Upload was successfully updated.' }
format.json { render :show, status: :ok, location: #upload }
else
format.html { render :edit }
format.json { render json: #upload.errors, status: :unprocessable_entity }
end
end
end
# DELETE /uploads/1
# DELETE /uploads/1.json
def destroy
#upload.destroy
respond_to do |format|
format.html { redirect_to uploads_url, notice: 'Upload was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_upload
#upload = Upload.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def upload_params
params.require(:upload).permit(:upload_title, :upload_description, :upload_datecreated, :user_id, :picture, :delete_picture)
end
end
Upload model:
class Upload < ActiveRecord::Base
belongs_to :user
has_attached_file :picture, styles: { large: "600x600#", medium: "300x300#", small: "150x150#", thumb: "50x50#" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :picture, content_type: /\Aimage\/.*\Z/
before_validation { image.clear if #delete_image }
def delete_picture
#delete_image ||= false
end
def delete_picture=(value)
#delete_image = !value.to_i.zero?
end
end
class Upload < ActiveRecord::Base
MAX_IMAGES = 6
validate :maximum_images
private
def count_valid_images
self.user.uploads.count
end
def maximum_images
errors.add(:base, "must have max #{MAX_IMAGES} images") if count_valid_images > MAX_IMAGES
end
end
My issue is, when I am under the camper show page
Current Camper URL:
campers/1
and I go to click on to view the appointment it uses the camper_id for the appointment_id which is wrong so say if the camper_id is 1 it will use the appointment_id as 1 and actually the appointment id is 3, so then it says Couldn't find appointment with id of 1.
Table Header
<% #appointments.each do |app| %>
<%= link_to app.camper.camperName, appointment_path(#camper, #appointment) %>
Campers Controller Show Action
#appointments = #camper.appointments
Camper Model
has_many :appointments, dependent: :destroy
Appointment Model
belongs_to :camper
Shallow Nested Routes File
resources :customers, shallow: :true do
resources :campers do
resources :appointments do
resources :orders do
member do
patch :complete
end
end
end
end
end
Camper Controller
class CampersController < ApplicationController
before_action :set_camper, only: [:show, :edit, :update, :destroy]
# before_action :set_customer, only: [:index, :new, :edit, :create, :update]
load_and_authorize_resource
# GET /campers
# GET /campers.json
def index
#campers = #customer.campers
end
def list
query = params[:q].presence || ""
#campers = Camper.search(query, page: params[:page], per_page: 20, order: {created_at: :desc} )
end
# GET /campers/1
# GET /campers/1.js
def show
#appointments = #camper.appointments
respond_to do |format|
format.html
format.json
end
end
# GET /campers/new
def new
#customer = Customer.find(params[:customer_id])
#camper = #customer.campers.build
end
# GET /campers/1/edit
def edit
end
def page_name
"Campers"
end
# POST /campers
# POST /campers.json
def create
#camper = Camper.new(camper_params)
respond_to do |format|
if #camper.save
format.html { redirect_to camper_path(#camper), notice: 'Camper was successfully created.' }
format.json { render :show, status: :created, location: #camper }
else
format.html { render :new }
format.json { render json: #camper.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /campers/1
# PATCH/PUT /campers/1.json
def update
respond_to do |format|
if #camper.update(camper_params)
format.html { redirect_to camper_path(#camper), notice: 'Camper was successfully updated.' }
format.json { render :show, status: :ok, location: #camper }
else
format.html { render :edit }
format.json { render json: #camper.errors, status: :unprocessable_entity }
end
end
end
# DELETE /campers/1
# DELETE /campers/1.json
def destroy
#camper.destroy
respond_to do |format|
format.html { redirect_to root_path, notice: 'Camper was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_camper
#camper = Camper.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def camper_params
params.require(:camper).permit(:order_id, :customer_id, :year, :manufacturer, :modelName, :camperClass, :vin, :mileage, :notes, :user_id)
end
end
Appointments Controller
class AppointmentsController < ApplicationController
before_action :set_appointment, only: [:show, :edit, :update, :destroy]
# GET /appointments
# GET /appointments.json
def index
#camper = Camper.find(params[:camper_id])
#appointments = #camper.appointments
end
# GET /appointments/1
# GET /appointments/1.json
def show
#orders = #appointment.orders
end
# GET /appointments/newå
def new
#camper = Camper.find(params[:camper_id])
#appointment = #camper.appointments.build
end
# GET /appointments/1/edit
def edit
end
# POST /appointments
# POST /appointments.json
def create
#appointment = Appointment.new(appointment_params)
respond_to do |format|
if #appointment.save
format.html { redirect_to appointment_path(#appointment), notice: 'Appointment was successfully created.' }
format.json { render :show, status: :created, location: #appointment }
else
format.html { render :new }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /appointments/1
# PATCH/PUT /appointments/1.json
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to #appointment, notice: 'Appointment was successfully updated.' }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /appointments/1
# DELETE /appointments/1.json
def destroy
#appointment.destroy
respond_to do |format|
format.html { redirect_to camper_appointments_path(#appointment), notice: 'Appointment was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def appointment_params
params.require(:appointment).permit(:customer_id, :camper_id, :order_id, :title, :description, :date_in, :date_out)
end
end
appointment_path only takes a single appointment argument. Remove the #camper argument:
appointment_path(#appointment)
I want show a daycare details on show page but I got this error
NoMethodError : undefined method `find' for nil:NilClass
from daycare controller file and i'm not get any idea. I have mentioned below that error line.
This is my Controller file
class DayCaresController < ApplicationController
before_filter :authenticate_user!
before_action :set_day_care, only: [:show, :edit, :update, :destroy]
# GET /day_cares
# GET /day_cares.json
def index
#day_cares = DayCare.all
end
# GET /day_cares/1
# GET /day_cares/1.json
def show
end
# GET /day_cares/new
def new
#day_care = DayCare.new
end
# GET /day_cares/1/edit
def edit
end
# POST /day_cares
# POST /day_cares.json
def create
#day_care = current_user.build_day_care(day_care_params)
respond_to do |format|
if #day_care.save
UserMailer.welcome_email(#user).deliver
format.html { redirect_to #day_care, :gflash => { :success => 'Day care was successfully created.'} }
format.json { render :show, status: :created, location: #day_care }
else
format.html { render :new }
format.json { render json: #day_care.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /day_cares/1
# PATCH/PUT /day_cares/1.json
def update
respond_to do |format|
if #day_care.update(day_care_params)
format.html { redirect_to #day_care, :gflash => { :success => 'Day care was successfully updated.'} }
format.json { render :show, status: :ok, location: #day_care }
else
format.html { render :edit }
format.json { render json: #day_care.errors, status: :unprocessable_entity }
end
end
end
# DELETE /day_cares/1
# DELETE /day_cares/1.json
def destroy
#day_care.destroy
respond_to do |format|
format.html { redirect_to day_cares_url, :gflash => { :success => 'Day care was successfully destroyed.'} }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions
def set_day_care
#day_care = current_user.day_care.find(params[:id]) # => **I got error this line**
end
# Never trust parameters from the scary internet, only allow the white list through.
def day_care_params
params.require(:day_care).permit(:name, :address, :office_phone, :cell_phone, :logo, :website, :user_id)
end
def dashboard
end
def profile
end
end
If user has_many: day_cares then use this name instead of day_care:
#day_care = current_user.day_cares.where(id: params[:id]).take
or probably as you wrote:
#day_care = current_user.day_cares.find(params[:id])
But with arrays instead of single instance (day_cares).
Also you can use just:
#day_care = DayCare.find(params[:id])
If you search by id. Or if you need to check that it's users day_care:
#day_care = DayCare.where(id: params[:id], user: current_user).take
current_user.day_care.find is not available, because you can only perform queries on plural associations. So given that the model associations are setup correctly as:
class User < ActiveRecord:Base
has_many :day_cares
...
end
the solution is probably just to resolve the spelling error from
`current_user.day_care.find` #wrong!
to
`current_user.day_cares.find` #right!
I have basic form that is accessed, for example via: http://url.com/rentals/new/dvd/10.
The problem is when form error happens I can't redirect it to the same page with the same
url segments and show the form error messages.
rentals_controller.rb:
def create
#rental = Rental.new(rental_params)
respond_to do |format|
if #rental.save
format.html { redirect_to #rental, notice: 'Rental was successfully created.' }
format.json { render :show, status: :created, location: #rental }
else
format.html { render :new }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
routes.rb
get 'rentals/new/dvd/:dvd_id' => 'rentals#new', as: :new_dvd_rental
I have the following models created:
dvd.rb
class Dvd < ActiveRecord::Base
has_many :rentals
has_many :users, through: :rentals
validates :title, presence: true
validates :year, inclusion: {in: 1900..Time.now.year.to_i}, :presence => {:message => 'Year must be from 1900 till current year.'}
validates :length, inclusion: {in: 1..999}, :presence => {:message => 'DVD length must be in minutes in range 1..999.'}
end
rental.rb
class Rental < ActiveRecord::Base
belongs_to :user
belongs_to :dvd
validates :user_id, presence: true
validates :total_price, presence: true
end
user.rb
class User < ActiveRecord::Base
has_many :rentals
has_many :dvds, through: :rentals
end
As well as rentals_controller.rb:
class RentalsController < ApplicationController
before_action :set_rental, only: [:show, :edit, :update, :destroy]
# GET /rentals
# GET /rentals.json
def index
#rentals = Rental.all
end
# GET /rentals/1
# GET /rentals/1.json
def show
end
# GET /rentals/new
def new
#rental = Rental.new
#users = User.all
#dvd = Dvd.find(params[:dvd_id])
end
# GET /rentals/1/edit
def edit
end
# POST /rentals
# POST /rentals.json
def create
#rental = Rental.new(rental_params)
respond_to do |format|
if #rental.save
format.html { redirect_to #rental, notice: 'Rental was successfully created.' }
format.json { render :show, status: :created, location: #rental }
else
format.html { render :new }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /rentals/1
# PATCH/PUT /rentals/1.json
def update
respond_to do |format|
if #rental.update(rental_params)
format.html { redirect_to #rental, notice: 'Rental was successfully updated.' }
format.json { render :show, status: :ok, location: #rental }
else
format.html { render :edit }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
# DELETE /rentals/1
# DELETE /rentals/1.json
def destroy
#rental.destroy
respond_to do |format|
format.html { redirect_to rental_url, notice: 'Rental was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_rental
#rental = Rental.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def rental_params
params.require(:rental).permit(:dvd_id, :user_id, :rent_date, :return_date, :total_price, :returned)
end
end
I've tried to modify rental controller like this, but still do not know how to pass other segments like new and dvd:
render :action => "new", :dvd_id => params[:dvd_id]
Any ideas?
I think if you draw a more restful route like this
resources :dvds do
resources :rentals
end
you will get the routes like http://url.com/dvd/10/rentals/new
here you will always get dvd_id
and in rentals_controller create method look like
def create
#dvd = Dvd.find(params[:dvd_id])
#rental = Rental.new(rental_params)
respond_to do |format|
if #rental.save
format.html { redirect_to #rental, notice: 'Rental was successfully created.' }
format.json { render :show, status: :created, location: #rental }
else
format.html { render :new }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
-- Waiting for #Sanket's ideas
Routes
The issue will almost certainly be with your redirect_to method
The problem is that your controller doesn't know you're using a nested resource, and consequently when you redirect to an object, it will likely just take you to the simplest route it can find
I would try this:
def create
...
else
format.html { render your_nested_resource_path(dvd_id: params[:dvd_id], other: params[:params]) }
...
end
This allows you to send the request to the nested route, which Rails won't route to without support