6

I'm trying to make a create product page in rails. This includes adding multiple images and text fields. I have one model for products and one for photos. I'm using the paperclip gem for photo upload. But I get no picture when I view product page. Photos are not being saved to database.

P.S. I use HAML.

app/views/products/show.html.haml

  %b Name
  = @product.name
  %br

  %b Description
  = @product.description

  %br
  - @product.photos.each do |photo|
  = image_tag photo.image.url

app/controllers/products_controller

class ProductsController < ApplicationController
  before_filter :require_login
    before_filter :current_user, only: [:create, :destory]

  def new 
    @product = Product.new
    @photo = Photo.new
    5.times { @product.photos.build }
  end

  def create

  @photo = current_user.photos.build(params[:photo])
  @product = current_user.products.build(params[:product])
    if @product.save
        render "show", :notice => "Sale created!"
    else
        render "new", :notice => "Somehting went wrong!"
    end
end

  def show
    @product = Product.find(params[:id]) 
  end

app/models/photo

class Photo < ActiveRecord::Base
  attr_accessible :product_id    
  belongs_to :product
  has_attached_file :image,
    :styles => {
      :thumb=> "100x100#",
      :small  => "300x300>",
      :large => "600x600>"
        }
end

app/models/product

class Product < ActiveRecord::Base
  attr_accessible :description, :name, :price, :condition, :ship_method, :ship_price, :quantity, :photo
  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos
  belongs_to :user
end

user model

   class User < ActiveRecord::Base
      attr_accessible :email, :password, :password_confirmation, :name

      attr_accessor :password
      has_many :products, dependent: :destroy
      has_many :photos,:through=>:products

app/products/new.html.haml

= form_for @product, :html => { :multipart => true } do |f|
  %p
    = fields_for :photos do |f_i|
      =f_i.file_field :image 
3

5 Answers 5

3

First your form is wrong, q for registration of photos used fields_for, then you use fields_for f.object.photos or use Photo.new do | g |, the other in your relationship model is wrong has_attached_file is has_many photos, the has_attached_file Paperclip is proper to be used in the model to be used not in the relationship with the other model. Hope this helps, now to have a product with several photographs, I recommend you use the gem cocoon, I q goes according to your case, https://github.com/nathanvda/cocoon

Sign up to request clarification or add additional context in comments.

1 Comment

This is not articulate enough
3
+50

You had written under Photo model as:

has_many :photos, :through => :products

This doesn't make any sense.. in your Photo model write

belongs_to :product

while in Product model write:

has_many :photos

actually this will be one-to-many relation as far i had understood:

There is no need to write has_attached_file in product model. This will be written under photo model like

has_attached_file :image

Now you have multiple photos for product. So you need loop for showing those photos. e.g., in your show view do some thing

<% unless @product.photos.blank? %>
  <% @product.photos.each do |photo| %>
    <%= image_tag photo.image.url %>
  <% end %>
<% end %>

_______ EDIT 2 ________

in your Product model

has_many :photos, :dependent => :destroy
accepts_nested_attributes_for :photos, :allow_destroy => true
attr_accessible :photos_attributes

in your photo model

belongs_to :product
attr_accessible :product_id

in your products controller

def new 
  @product = Product.new
  5.times { @product.photos.build }
end

def create
  @product = Product.new(params[:product])
  @product.user_id = current_user.id
  if @product.save
      render "show", :notice => "Sale created!"
  else
      render "new", :notice => "Somehting went wrong!"
  end
end

in your new.html.haml

= form_for @product, :html => { :multipart => true } do |f|
  - if @product.errors.any?
    .error_messages
      %h2 Form is invalid
      %ul
        - for message in @product.errors.full_messages
          %li
            = message
  %p
    = f.fields_for :photos do |f_i|
      =f_i.file_field :image 

try out now. !

2 Comments

huh ... thats weird they are not
any ideas on what i should do
1

After looking at your code. Its quite straight forward that Product don't have any image attribute at all. Photo have image attribute.

So you have to access Products -> photos -> images

Do this in controller show action

@product = Product.find(id)
@photos = @product.photos

In show.html.erb

[email protected] do |photo|
= image_tag photo.image.url
-end

For haml syntax my applogies as these days working on project using html.erb. SO correct haml syntax if there is any error.

Comments

-1

I think

5.times { @product.photos.build }

should be in #new method cuz .build method interact with @fields_for

1 Comment

His relationship between models messed up.
-1
   @product.image requires image to be the attribute of product model means image fields should be in products table.

   @product.image should be @product.photo.image.url

2 Comments

Didn't work i end up getting undefined method `photos' for nil:NilClass
there are multiple photos for product.. @product.photo will not work, i guess need a loop for displaying all photos!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.