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
Related
I am making a sort of checklist section for my site. I have a model called commission that will contain data about a commissioning task. What I need to do is when a new commission entry is created I need to create a series of about 30 commission tasks that will link to it. A sort of checklist of predefined values for a person to go down through and check. What would be the best way to do this?
Here are my models and controller:
commission.rb
class Commission < ApplicationRecord
has_many :comtasks
belongs_to :project
belongs_to :user
accepts_nested_attributes_for :comtasks, allow_destroy: true
end
comtask.rb
class Comtask < ApplicationRecord
belongs_to :commission
belongs_to :user
end
commissions_controller.rb
class CommissionsController < ApplicationController
before_action :set_commission, only: [:show, :edit, :update, :destroy]
# GET /commissions
# GET /commissions.json
def index
#commissions = Commission.all
end
# GET /commissions/1
# GET /commissions/1.json
def show
end
# GET /commissions/new
def new
#commission = Commission.new
end
# GET /commissions/1/edit
def edit
end
# POST /commissions
# POST /commissions.json
def create
#commission = Commission.new(commission_params)
respond_to do |format|
if #commission.save
format.html { redirect_to #commission, notice: 'Commission was successfully created.' }
format.json { render :show, status: :created, location: #commission }
else
format.html { render :new }
format.json { render json: #commission.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /commissions/1
# PATCH/PUT /commissions/1.json
def update
respond_to do |format|
if #commission.update(commission_params)
format.html { redirect_to #commission, notice: 'Commission was successfully updated.' }
format.json { render :show, status: :ok, location: #commission }
else
format.html { render :edit }
format.json { render json: #commission.errors, status: :unprocessable_entity }
end
end
end
# DELETE /commissions/1
# DELETE /commissions/1.json
def destroy
#commission.destroy
respond_to do |format|
format.html { redirect_to commissions_url, notice: 'Commission was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_commission
#commission = Commission.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def commission_params
params.require(:commission).permit(:project_id, :user_id, :description, :objectname, :location, comtasks_attributes: [:id, :content, :notes])
end
end
Any thoughts or suggestions are appreciated.
below is the idea,
def create
#commission = Commission.create!(commission_params)
# use create not new to generate #commission.id value
# so comtask records can use the id value as reference
create_comtasks_job
# for comtask create I put in other method
respond_to do |format|
if #commission.save
format.html { redirect_to #commission, notice: 'Commission was successfully created.' }
format.json { render :show, status: :created, location: #commission }
else
format.html { render :new }
format.json { render json: #commission.errors, status: :unprocessable_entity }
end
end
end
def create_comtasks_job
# loop 30 tasks / or manual as follow
#commission.comtasks.build(content: 'content1',notes:'notes1')
#commission.comtasks.build(content: 'content2',notes:'notes2')
end
additional code for your model
make sure for your model has relation like sample below
for your model
class Commission < ActiveRecord::Base
has_many :comtasks
end
class Comtask < ActiveRecord::Base
belongs_to :commission
end
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%>
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"
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!
OK - So I have a PINS models that basically allows users to upload images (pins). On the main page of the site I would like to query and show users how many total images have been loaded into the database - I use paperclip and devise: What do I need to do to count and show the total number of Pins ? Thank everyone for taking the time to help with this inquiry :)
Here is my pins model:
class Pin < ActiveRecord::Base
attr_accessible :description, :image, :tag_list, :image_remote_url
has_attached_file :image, styles: { medium: "320x300>" }
validates :description, presence: true
validates :user_id, presence: true
validates_attachment :image, presence: true,
content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', ] },
size: { less_than: 100.megabytes }
belongs_to :user
has_attached_file :image, styles: { medium: "320x300"}
def image_remote_url=(url_value)
self.image = URI.parse(url_value) unless url_value.blank?
super
end
acts_as_taggable
def next_image
self.class.where('id > ?', self.id).order('id asc').first
end
def previous
self.class.where('id < ?', self.id).order('id desc').first
end
end
and my controller:
class PinsController < ApplicationController
before_filter :authenticate_user!, except: [:show, :index]
# GET /pins
# GET /pins.json
def index
if params[:tag]
#pins = Pin.tagged_with(params[:tag]).order("created_at desc").paginate(:page => params[:page], :per_page => 100)
else
#pins = Pin.order("created_at desc").page(params[:page]).per_page(100)
#respond_to do |format|
#format.html
#format.atom
end
end
# #pins = Pin.all
#end
#end
# GET /pins/1
# GET /pins/1.json
def show
#pin = Pin.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #pin }
end
end
# GET /pins/new
# GET /pins/new.json
def new
#pin = current_user.pins.new
#pin_count = Pin.count
respond_to do |format|
format.html # new.html.erb
format.json { render json: #pin }
end
end
# GET /pins/1/edit
def edit
#pin = current_user.pins.find(params[:id])
end
# POST /pins
# POST /pins.json
def create
#pin = current_user.pins.new(params[:pin])
respond_to do |format|
if #pin.save
format.html { redirect_to #pin, notice: 'Pin was successfully created.' }
format.json { render json: #pin, status: :created, location: #pin }
else
format.html { render action: "new" }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# PUT /pins/1
# PUT /pins/1.json
def update
#pin = current_user.pins.find(params[:id])
respond_to do |format|
if #pin.update_attributes(params[:pin])
format.html { redirect_to #pin, notice: 'Pin was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
# DELETE /pins/1
# DELETE /pins/1.json
def destroy
#pin = current_user.pins.find(params[:id])
#pin.destroy
respond_to do |format|
format.html { redirect_to pins_url }
format.json { head :no_content }
end
end
end
#def pin_params
#params.require(:pin).permit(:description, :image)
#end
You're on One month Rails aren't you? Brilliant Tutorial :)
In your Pin Controller include the code in the Action you want (in your example the show action):
def show
# your other code here
#pin_count = Pin.count
# #count is now available in your view for `show`
end
Than you can call in your view => <%= #pin_count %>