Image upload using paperclip in ruby on rails - ruby-on-rails

I'm trying to upload image using paperclip. But the exception "NoMethodError in Shop::ProductsController#create undefined method `chomp' for nil:NilClass" occurs. Can anyone see and highlight the problem please?
Here is Gemfile code
gem 'paperclip', '~> 4.2.1'
Controller
class Shop::ProductsController < ApplicationController
layout "shop"
def index
#products = Product.find_by_shop_id(session[:shop_id]).sort_by_name
# #products = Product.products.sort_by_name
end
def show
#product = Product.find(params[:id])
end
def new
#product = Product.new
end
def edit
#product = Product.find(params[:id])
end
def create
#product = Product.new(product_params)
#product.shop = Shop.find(session[:shop_id].to_i)
if #product.save
redirect_to :action => 'new'
else
render 'new'
end
end
def update
#product = Product.find(params[:id])
if #product.update(product_params)
redirect_to admin_products_path
else
render 'edit'
end
end
def destroy
#product = Product.find(params[:id])
#product.destroy
redirect_to admin_products_path
end
private
def product_params
params.require(:product).permit(:name, :desc, :price, :display, :status)
end
end
View
<%= form_for [:shop, #product] do |f| %>
<div class="box-body">
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, :class => 'form-control', :placeholder => 'City name' %>
</div>
<div class="form-group">
<%= f.label "Description" %>
<%= f.text_area :desc, :class => 'form-control', :placeholder => 'Write description here...', :rows => 5 %>
</div>
<div class="form-group">
<%= f.label :price %>
<%= f.text_field :price, :class => 'form-control', :placeholder => '0.0' %>
</div>
<div class="form-group">
<%= f.label :display %>
<%= f.file_field :display %>
</div>
<div class="checkbox">
<label>
<%= f.check_box :status %> Is enabled?
</label>
</div>
</div><!-- /.box-body -->
<div class="box-footer">
<%= f.submit :class => "btn btn-primary" %>
</div>
<% end %>
Model
class Product < ActiveRecord::Base
has_attached_file :display, :styles => {:thumb => "500x500>"}
validates_attachment_content_type :display, :content_type => /\Aimage\/.*\Z/
scope :enabled, lambda {where("products.status = 1")}
scope :sort_by_name, lambda { order("products.name asc")}
end

You need to install ImageMagik in your machine
Install ImageMagik
And for windows 7+
Install File.exe

Related

Carrierwave Gem Not Working

I really have no idea what to do now. Image is showing up as nil in database. There are no errors showing up.
Model
class Resource < ActiveRecord::Base
mount_uploader :image, ImageUploader
attr_accessible :title, :url, :description, :tag
validates :title, presence: true, uniqueness: true
validates :url, presence: true
validates :description, presence: true
validates :tag, presence: true
belongs_to :user
acts_as_votable
validates_processing_of :image
validate :image_size_validation
private
def image_size_validation
errors[:image] << "should be less than 500KB" if image.size > 0.5.megabytes
end
end
Image Uploader
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process :resize_to_fill => [100, 100]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
Form Partial
<%= form_for #resource, html: { multipart: true } do |f| %>
<% if #resource.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#resource.errors.count, "error") %> prohibited this pet
from being saved:</h2>
<ul>
<% #resouce.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :url %><br>
<%= f.text_area :url%>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :tag %><br>
<%= f.text_area :tag %>
<div class="field">
<%= f.label :image %><br>
<%= f.file_field :image %>
<% if f.object.image? %>
<%= image_tag f.object.image.thumb.url %>
<%= f.label :remove_image %>
<%= f.check_box :remove_image %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
Image tag in show
<%= image_tag #resource.image.thumb.url %>
Controller
class ResourcesController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
def index
#resources = Resource.page(params[:page]).per(15)
end
def show
#resource = Resource.where(:id => params[:id]).first
end
def edit
#resource = Resource.where(:id => params[:id]).first
end
def new
#resource = current_user.resources.build
end
def update
#resource = Resource.where(:id => params[:id]).first
respond_to do |format|
if #resource.update_attributes(resources_params)
format.html { redirect_to #resource, :notice => 'Resource was successfully
updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #resource.errors, :status =>
:unprocessable_entity }
end
end
end
def destroy
#toDelete = Resource.where(:id => params[:id]).first
puts #toDelete.id
if #toDelete.destroy
flash[:notice] = "Successfully deleted post!"
redirect_to root_path
else
flash[:alert] = "Error updating post!"
end
end
def create
#resource= current_user.resources.build(resources_params)
if #resource.save
redirect_to root_path
flash[:alert] = "Successfully created new resource!"
else
render "new"
end
end
def upvote
#resource = Resource.find(params[:id])
#resource.upvote_by current_user
redirect_to :back
end
def downvote
#resource = Resource.find(params[:id])
#resource.downvote_from current_user
redirect_to :back
end
private
def resources_params
params.require(:resource).permit(:title, :url, :description, :image, :tag)
end
end
If there is any other file you would like to see, I will post it.
Thank You.
EDIT
It was just a versioning problem......

Ruby on Rails: No routes match for[POST] '/contacts/new'

Rails 5. keep getting the error that route could not be found. What did I do wrong here?
App/views/contacts/new.html.erb
<%= form_for "#contact" do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
routes.rb file
Rails.application.routes.draw do
root to: 'pages#home'
get '/about', to: 'pages#about'
resources :contacts
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
redirect_to new_contact_path, notice: "Message sent."
else
redirect_to new_contact_path, notice: "Error occured."
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
end
contact.rb (model file, blank for now)
class Contact < ActiveRecord::Base
end
I can't figure out why. Thanks in advance.
You have quotes around your #contact variable in your form, try just using the plain #contact variable.

DRY controller .valid? for create and update using simple_form

So I've got these views:
new.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Expose Your Hidden Gem</h1>
<%= simple_form_for #place do |f| %>
<%= f.input :name, error: "Name is mandatory" %>
<%= f.input :address %>
<%= f.input :description %>
<br />
<%= f.submit 'Create', class: 'btn btn-primary' %>
<% end %>
</div>
edit.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Edit Your Place</h1>
<%= simple_form_for #place do |f| %>
<%= f.input :name %>
<%= f.input :address %>
<%= f.input :description %>
<br />
<%= f.submit 'Update', class: 'btn btn-primary' %>
<% end %>
</div>
this model:
Place.rb
class Place < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
has_many :photos
geocoded_by :address
after_validation :geocode
validates :name, presence: true
validates :address, presence: true
validates :description, presence: true
end
And finally, places_controller.rb (only showing create and update)
def create
#place = current_user.places.create(place_params)
if #place.save
redirect_to root_path
else
render :new
end
end
def update
#place = Place.find(params[:id])
if #place.user != current_user
return render text: 'Not Allowed', status: :forbidden
end
#place.update_attributes(place_params)
if #place.save
redirect_to root_path
else
render :edit
end
end
But, I'm trying to think DRY and want to know if there is a better way to do a validation for name address and description presence without having the same identical code in both the create and update portions of my controller? I feel like I should just be writing it once...
First, you can refactor your views to use the following structure:
# new.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Expose Your Hidden Gem</h1>
<%= render 'form' %>
</div>
# edit.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Edit Your Place</h1>
<%= render 'form' %>
</div>
# _form.html.erb
<%= simple_form_for #place do |f| %>
<%= f.input :name %>
<%= f.input :address %>
<%= f.input :description %>
<br />
<% submit_label = #place.new_record? ? 'Create' : 'Update' %>
<%= f.submit submit_label, class: 'btn btn-primary' %>
<% end %>
And then in your controllers you could refactor to:
def create
#place = current_user.places.new(place_params)
if #place.save
redirect_to root_path
else
render :new
end
end
def update
#place = current_user.places.find(params[:id])
#place.attributes = place_params
if #place.save
redirect_to root_path
else
render :edit
end
end

How do I create recurring events with simple form and Ruby? Is ice-cube the best gem for this?

I'm building an events app using Rails and I need to figure out how Users can create Events which will be recurring - daily, weekly, monthly, yearly if they so wish.
It's not completely clear how to do this from my research but most roads seem to point toward using the ice_cube gem along with another - either schedulable or recurring_select for the form.
Is this the best way forward? If so, which is the best route and, if not, what is the best alternative?
Initially I want the form to offer an either/or option of 'recurring' or 'one-day' event. I'm using simple_form for all of my forms.
Here's the Event MVC position at the moment.
Event.rb -
class Event < ActiveRecord::Base
# You can call the scope whatever.
# the focus below is on the :date attribute from the events table - see also controller for index method/action
scope :not_yet_happened, -> { where('date >= ?', Date.current) }
belongs_to :category
belongs_to :user
has_many :bookings
has_many :comments
has_attached_file :image, styles: { medium: "300x300>" }
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
validates :title, :description, :location, :date, :time, :number_of_spaces, :price_pennies, :category_id, presence: true
validates :title, length: { minimum: 4 }
validates :description, length: { maximum: 250, too_long: "%{count} characters is the maximum allowed" }
monetize :price_pennies
# required for money-rails gem to function
end
events_controller.rb -
class EventsController < ApplicationController
before_action :find_event, only: [:show, :edit, :update, :destroy,]
# the before_actions will take care of finding the correct event for us
# this ties in with the private method below
before_action :authenticate_user!, except: [:index, :show]
# this ensures only users who are signed in can alter an event
def index
if params[:category].blank?
#events = Event.not_yet_happened.order("created_at DESC")
else
#category_id = Category.find_by(name: params[:category]).id
#events = Event.not_yet_happened.where(category_id: #category_id).order("created_at DESC")
end
# The above code = If there's no category found then all the events are listed
# If there is then it will show the EVENTS under each category only
end
def show
end
def new
#event = current_user.events.build
# this now builds out from a user once devise gem is added
# after initially having an argument of Event.new
# this assigns events to users
end
# both update and create actions below use event_params as their argument with an if/else statement
def create
#event = current_user.events.build(event_params)
# as above this now assigns events to users
# rather than Event.new
if #event.save
redirect_to #event, notice: "Congratulations, you have successfully created a new event."
else
render 'new'
end
end
def edit
# edit form
# #edit = Edit.find(params[:id])
#event = current_user.events.find(params[:id])
end
def update
if #event.update(event_params)
redirect_to #event, notice: "Event was successfully updated!"
else
render 'edit'
end
end
def destroy
#event.destroy
redirect_to root_path
end
private
def event_params
params.require(:event).permit(:title, :location, :date, :time, :description, :number_of_spaces, :is_free, :price, :organised_by, :url, :image, :category_id)
# category_id added at the end to ensure this is assigned to each new event created
end
def find_event
#event = Event.find(params[:id])
end
end
_form.html.erb (events) -
<%= simple_form_for(#event, html: { :class => "form-inline" }) do |f| %>
<% if #event.errors.any? %>
<h2><%= pluralize(#event.errors.count, "error") %> prevented this Event from saving:</h2>
<ul>
<% #event.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<div class="form-group">
<%= f.collection_select :category_id, Category.all, :id, :name, {prompt: "Choose a category"} %>
<!-- The above code loop assigns a category_id to each event -->
</div>
<div class="form-group">
<%= f.input :image, as: :file, label: 'Image', class: "form-control" %>
</div>
<div class="form-group">
<%= f.input :title, label: false, placeholder: 'Title', class: "form-control" %>
</div>
<div class="form-group">
<%= f.text_field :location, id: 'geocomplete', class: "form-control" %>
</div>
<div class="form-group">
<%= f.text_field :date, placeholder: 'Date', id: 'datepicker', class: "form-control" %>
</div>
<div class="form-group">
<%= f.input :time, label: 'What time does the event start?', class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.input_field :description, label: false, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :number_of_spaces %>
<%= f.text_field :number_of_spaces, label: 'Number of spaces', class: "form-control" %>
</div>
<div class="form-group">
<%= f.input :is_free, label: 'Tick box if Event is free of charge', class: "form-control" %>
<!--f.input :currency, :collection => [['£GBP - British Pounds',1],['$USD - US Dollars',2],['€EUR - Euros',3]] -->
</div>
<div class="form-group">
<%= f.label :cost_per_person %>
<%= f.input :price, label: '(leave blank if free of charge)', class: "form-control" %>
</div>
<div class="form-group">
<%= f.input :organised_by, class: "form-control" %>
</div>
<div class="form-group">
<%= f.input :url, label: "My Website", class: "form-control" %>
</div>
<div class="form-group">
<%= f.button :submit, label: 'Submit', class: "btn btn-primary" %>
<% end %>
</div>
Mike. The fastest way is to use ice_cube + schedulable gems combo. Go through the Readme and you will be set up in minutes. It also features past_event_occurrences and future_event_occurrences.

Rails nested attributes are not saving

I am new to rails and am learning to complete an Inventory System database project for school.
Here is my Item model:
class Item < ActiveRecord::Base
self.primary_key ='item_id'
validates :item_id, :presence => true
has_one :vendor_item, :dependent => :destroy
has_one :vendor, :through => :vendor_item
accepts_nested_attributes_for :vendor_item
end
Here is my item controller:
class ItemsController < ApplicationController
def new
#item = Item.new
#all_vendors = Vendor.all
#item_vendor = #item.build_vendor_item
end
def create
#item = Item.new(item_params)
vendor = params[:vendors][:id]
#item_vendor = #item.build_vendor_item(:vendor_id => vendor)
#item_vendor.save
#raise params.inspect
if #item.save
redirect_to #item
else
render 'new'
end
end
def show
#item = Item.find(params[:id])
#item_vendor = #item.vendor_item
end
def index
#items = Item.all
end
def priceUnder500
#priceUnder500 = Item.where("price < ?", 500)
respond_to do |format|
format.html
format.js
end
end
def priceOver500
#priceOver500 = Item.where("price > ?", 500)
respond_to do |format|
format.html
format.js
end
end
def edit
#item = Item.find(params[:id])
#all_vendors = Vendor.all
#vendor_item = #item.vendor_item
end
def update
#item = Item.find(params[:id])
vendor = params[:vendors][:id]
if #item.vendor_item.blank?
#item.build_vendor_item(:vendor_id => vendor)
end
if #item.update(params[:item].permit(:item_id, :name, :category, :description, :reorder_level, :quantity, :price, :vendor_item_attributes => [:vendor_item_id]))
redirect_to items_path
else
render 'edit'
end
end
def destroy
#item = Item.find(params[:id])
#item.destroy
redirect_to items_path
end
private
def item_params
params.require(:item).permit(:item_id, :name, :category, :description, :reorder_level, :quantity, :price, :vendor_item_attributes => [:vendor_item_id])
end
end
And my _form partial for items:
<%= form_for #item do |f| %>
<% if #item.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#item.errors.count, "error") %> prohibited
this post from being saved:</h2>
<ul>
<% #item.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :item_id, 'Item Id' %><br>
<%= f.text_field :item_id %>
</p>
<%= fields_for #item_vendor do |vii| %>
<div class= "vendorItemId">
<%= vii.label :vendor_item_id%>
<%= vii.text_field :vendor_item_id%><br>
</div>
<% end %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :category %><br>
<%= f.text_field :category %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.label :reorder_level %><br>
<%= f.text_field :reorder_level %>
</p>
<p>
<%= f.label :quantity %><br>
<%= f.text_field :quantity %>
</p>
<p>
<%= f.label :price %><br>
<%= f.text_field :price %>
</p>
<h3>Vendors:</h3>
<%= fields_for(#item_vendor) do |ab| %>
<div class= "field">
<%= ab.label "All Vendors:" %><br>
<%= collection_select(:vendors, :id, #all_vendors, :id, :name, {},{:multiple => false})%>
</div>
<% end %>
<p>
<%= f.submit %>
</p>
<% end %>
vendor_item contains a reference to item_id, vendor_id, and has another attribute of vendor_item_id. When the program saves, item_id and vendor_id save but vendor_item_id does not save. I have tried every online source but cannot seem to get that one attribute to save. I am using rails 4. Thanks in advance for any help provided.
You haven't saving the result in an instance variable in create action.
Try giving like this in your create action.
def create
#item = Item.new(item_params)
vendor = params[:vendors][:id]
#item_vendor = #item.build_vendor_item(:vendor_id => vendor)
if #item.save
redirect_to #item
else
render 'new'
end
end
def create
#item = Item.new(item_params)
#vendor = params["item"]["vendors"]
if #item.save
#item.create_vendor_item(#vendor.id => vendor).save
redirect_to #item
else
render 'new'
end
end

Resources