Reputation: 1
here is my _form.html.erb
<%= simple_form_for @book,:html => { :multipart => true } do |f| %>
<%= select_tag(:category_id, options_for_select(@categories), :promt => "Select a category") %>
<%= f.file_field :book_img %>
<%= f.input :title, label: "Book Title" %>
<%= f.input :description %>
<%= f.input :author %>
<%= f.button :submit %>
and here is my BooksController
class BooksController < ApplicationController
before_filter :initialize_book
before_action :find_book, only: [:show, :edit, :update, :destroy]
def initialize_book
@book = Book.new
end
def show
@book =Book.find(params[:id])
end
def index
if params[:category].blank?
@books = @books = Book.all.order("created_at DESC")
else
@category_id = Category.find_by(name: params[:category]).id
@books = Book.where(:category_id => @category_id).order("created_at DESC")
end
end
def new
@book = current_user.books.build # Book.new
@categories = Category.all.map{ |c| [c.name, c.id]}
end
def create
@book =current_user.books.build(book_params) # Book.new(book_params)
@book.category_id = params[:category_id]
if @book.save
redirect_to root_path
else
render 'new'
end
end
def edit
@categories = Category.all.map{ |c| [c.name, c.id]}
end
def update
@book.category_id = params[:category_id]
if @book.update(book_params)
redirect_to book_path(@book)
else
render 'edit'
end
end
def destroy
@book.destroy
redirect_to root_path
end
private
def book_params
params.require(:book).permit(:title, :description, :author, :category_id, :book_img)
end
def find_book
@book =Book.find(params[:id])
end
end
book.rb
class Book < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_attached_file :book_img, styles: { book_index: "250x250>", book_show: "325x475>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :book_img, content_type: /\Aimage\/.*\z/
end
I installing the paperclip gem to add image to Book and this is a file created when i run Rails migration generator: rails generate paperclip Book book_img
class AddAttachmentBookImgToBooks < ActiveRecord::Migration
def self.up
change_table :books do |t|
t.attachment :book_img
end
end
def self.down
remove_attachment :books, :book_img
end
end
But when i add Book and attrack an image to Book had show an error
NoMethodError in Books#create
Showing C:/Sites/BookReview/app/views/books/_form.html.erb where line #2 raised:
undefined method `map' for nil:NilClass
Trace of template inclusion: app/views/books/new.html.erb
Rails.root: C:/Sites/BookReview
Application Trace | Framework Trace | Full Trace
app/views/books/_form.html.erb:2:in `block in _app_views_books__form_html_erb___232429848_42489936'
app/views/books/_form.html.erb:1:in `_app_views_books__form_html_erb___232429848_42489936'
app/views/books/new.html.erb:3:in `_app_views_books_new_html_erb__358042162_78928608'
app/controllers/books_controller.rb:39:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"kuaFBEmKqeVwLRr+NWke5AS5GxqPK0O/rOSPwDrc+8GsERzW0AlTJvhUji8/OevAIYhETyKc+jiNC3XIvpTAxQ==",
"category_id"=>"3",
"book"=>{"book_img"=>#<ActionDispatch::Http::UploadedFile:0x91a4060 @tempfile=#<Tempfile:C:/Users/muitr/AppData/Local/Temp/RackMultipart20160822-11652-1id5vn1.jpg>,
@original_filename="csharp.jpg",
@content_type="image/jpeg",
Upvotes: 0
Views: 2746
Reputation: 968
You set categories only for edit action, but what with new? Try this:
before_action :set_categories, only: [:new,:create, :edit]
private
def set_categories
@categories = Category.all.map{ |c| [c.name, c.id]}
end
Upvotes: 2
Reputation: 2586
This line app/controllers/books_controller.rb:39:in create'
says the error occours within method create
. Within create
you don't set @categories
.
Your before filter and action only set @book
render :new
does not execute your new
method. It only renders the given template for new
. So @categories
is still nil
Upvotes: 1