codegirl codegirl - 1 month ago 12
Ruby Question

getting "undefined method `url' for "":String" Using paperclip in Ruby on Rails

I'm getting this error on the

app/views/cart/_cart.html.erb
page of an E-commerce app I'm building
undefined method 'url' for "":String
Did you mean? URI


If I exclude the line
<td><%= image_tag item.product.image.url(:thumb) %></td>
from the code I don´t get the messages and can see what is in the cart, but no small picture of the product in the cart.

It would be so nice if someone could help me out here since I'm a ROR newbie and can't figure it out on my own.

here is the
_cart.html.erb
view were the error is appearing

<% @cart.product_items.each do |item| %>

<table class="table">
<tr>
<th>Quantity</th>
<th>Name</th>
<th>Price &euro;</th>
<th>Image</th>

</tr>
<tr>
<td><%= item.quantity %>&times; </td>
<td><%= item.product.title %></td>
<td><%= number_to_currency(item.total_price_usd, :unit => '€ ', :precision => 0)%></td>
<td><%= image_tag item.product.image.url(:thumb) %></td>

</tr>

</table>




The app has model for Images, and it looks like this:

class Image < ActiveRecord::Base

belongs_to :product
has_many :product_items, :dependent => :destroy

has_attached_file :image, styles: { medium: "500x500#", thumb: "100x100#" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/

end


And the
product.rb
model is like this

class Product < ActiveRecord::Base
acts_as_list :scope => [:category, :label]
belongs_to :category
belongs_to :label

has_many :images
accepts_nested_attributes_for :images
has_many :product_items, :dependent => :destroy

extend FriendlyId
friendly_id :title, use: [:slugged, :finders]

#before_destroy :ensure_not_product_item

validates :title, :description, presence: true
validates :price_usd, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true

end


the
product_item.rb
model is like this:

class ProductItem < ActiveRecord::Base
belongs_to :product
belongs_to :cart
belongs_to :order

belongs_to :image

def total_price_usd
product.price_usd * quantity
end

end


I can see the product images in the
views/products/show
but when I have added a product to the cart and want to take a look at the items in the cart the app breaks with the error messages:
undefined method 'url' for "":String
Did you mean? URI


here is the
views/products/show.html.erb


<div class="col-xs-12 col-sm-6 center-block" >
<div id='carousel-custom' class='carousel slide' data-ride='carousel'>
<div class='carousel-outer'>
<!--slider -->
<div class='carousel-inner '>
<div class='item active'>
<%= image_tag @product.images.first.image.url(:medium),
class: "img-responsive", id: "" %>
</div>
<% @product.images.drop(1).each do |image_product| %>
<div class='item'>
<%= image_tag image_product.image.url(:medium),
class: "img-responsive", id: "" %>

</div>
<% end %>

<script>
$("#zoom_05").elevateZoom({ zoomType : "inner", cursor:
"crosshair" });
</script>
</div>
<!-- sag sol -->
<a class='left carousel-control' href='#carousel-custom' data-
slide='prev'>
<span class='glyphicon glyphicon-chevron-left'></span>
</a>
<a class='right carousel-control' href='#carousel-custom' data-
slide='next'>
<span class='glyphicon glyphicon-chevron-right'></span>
</a>
</div>
<!-- thumb -->
<ol class='carousel-indicators mCustomScrollbar meartlab'>
<li data-target='#carousel-custom' data-slide-to='0' class='active'>
<%= image_tag @product.images.first.image.url(:medium), class:
"img-responsive", id: "zoom_05" %>
</li>
<% @product.images[1..-1].each_with_index do |image_product, index|
%>
<li data-target='#carousel-custom' data-slide-to=<%= index + 1%>
>
<%= image_tag image_product.image.url(:medium), class: "img-
responsive", id: "" %>
</li>
<% end %>
</li>
</ol>
</div>

<script type="text/javascript">
$(document).ready(function() {
$(".mCustomScrollbar").mCustomScrollbar({axis:"x"});
});
</script>

</div>
</div>
</div>

Answer Source

You have has_many :images in Product. And Image model has attached file named image. So first you should fetch all images of a product with product.images, loop through each image and map the image url like below

#fetch all images of a product
<% item.product.images.each do |img| %>
  #map the url of each img
  <td><%= image_tag img.image.url(:thumb) %></td>
<% end %>

where img is an instance of Image and image is attached file name.

Having the file name(image) same as model name(image) will confuse things(as it did now). To keep things simple in the future, try a different name. For example, say avatar, then the above code would look like below

#fetch all images of a product
<% item.product.images.each do |img| %>
  #map the url of each img
  <td><%= image_tag img.avatar.url(:thumb) %></td>
<% end %>