lmtony
lmtony

Reputation: 43

Can't Get Photos to Work in Rails

I am having all kinds of trouble doing a simple task, displaying a photo as part of a result set for each one. I'm pretty new to Rails in general, coming from another language where I can do this in seconds.

The @photo query finds 0 records even though multiple records for photos are in the DB matching the property ID.

I'm not too sure what I'm doing wrong here.

Here are my relevant files:

app/controllers/properties_controller.rb:

class PropertiesController < ApplicationController

  ......

  def all
    # gets all of the properties and uses will_paginate
    @properties = Property.paginate(page: params[:page])

    # should get the first positioned photo matching the results in the @properties query
    @photos = Photo.where(:property_id => @properties.map(&:id)).order("position").first
  end

  # ......

end

app/models/property.rb:

class Property < ActiveRecord::Base

  belongs_to :listing_type
  belongs_to :property_type
  belongs_to :status

  has_many :photos

  # ......

end

app/models/photo.rb:

class Photo < ActiveRecord::Base
  mount_uploader :photoname, PhotoUploader

  belongs_to :property

  acts_as_list scope: :property_id

  validates :photoname, presence: true
  validates :property_id, presence: true
end

details.html.erb:

<% @properties.reverse_each do |property| %>
  <div class="item col-md-4">
    <div class="image">
      <%= link_to property_path(property) do %>
        <span class="btn btn-default"><i class="fa fa-file-o"></i> Details</span>
      <% end %>
      <%= image_tag(property) %>
    </div>

  # ......

<% end %>

Upvotes: 0

Views: 49

Answers (2)

lmtony
lmtony

Reputation: 43

After a TON of help from @МалъСкрылевъ, which also had me learning a few new ways of "thinking" this in general, his answer led me to rethink what I was doing and go back to simply starting over and reconstructing what ended up being VERY basic. All I needed to do was make the photo query for the first photo in my loop over the properties. DUH! Here's what I did in case it helps some other poor new Rails developer!

properties_controller.rb

class PropertiesController < ApplicationController

  ......

  def all
    # gets all of the properties and uses will_paginate
    @properties = Property.paginate(page: params[:page])

  ......

end

details.html.erb

<% @properties.each do |property| %>
<div class="item col-md-4">
  <% @photo = Photo.where(property_id: property.id).order("position").first %>
  <div class="image">
    <%= link_to property_path(property) do %>
      <span class="btn btn-default"><i class="fa fa-file-o"></i> Details</span>
    <% end %>
    <%= image_tag(@photo.photoname.medium) %>
  </div>

  ......

Upvotes: 0

Малъ Скрылевъ
Малъ Скрылевъ

Reputation: 16507

Since you have a has_many realtion in the Property, you have to just access to the relation of the property to read all teh photoes:

photo = @property.photos.order("position").first

Well if you need to grab all the photoes of properties, use include to properties grab:

@properties = Property.includes(:photos).paginate(page: params[:page]).reverse

the include is needed to avoid N + 1 problem, then try replacing it with a first photo:

@photos = @properties.map { |pr| pr.photos.order("position").first }

Mpve reverse to controller, and to use @photos along with @properties use index:

<% @properties.each.with_index do |property, i| %>
   #...
   <%= image_tag(@photos[i]) %>
<- end >

NOTE that the code selecting an image pr.photos... be better moved to a decorator (see gem draper).

Upvotes: 1

Related Questions