0

I am very new to Rails and Web-programming and hope you can help me out with my very first project. I am developing a website for a Real Estate Agency.

I have 3 tables in my database (Homes: Home_ID, Home_Name, Admin_ID; Admins: Admin_ID, Admin_Name, Admin_Email; Images: Image_ID, Image_Path, Image_Name, Home_ID, Admin_ID).

All 3 tables have been created using scaffold. The image information (name, path, image_id, home_id etc) have been entered in SQLite. I get all text information of the different houses displayed correctly on the website except the pictures.

My attempt to link it in the view/home/index.html.erb created the following error:

undefined method `image_path' for #<Home:0xb63d85e0>

I used below code:

<% @homes.each do |home| %>
  <tr>
    <td><%= home.name %></td>
    <td><%= home.details %></td>
    <td><%= home.region %></td>
    <td><%= home.address %></td>
    <td><%= home.price %></td>
    <td><%= home.admin_id %></td>
    <td><%= home.image_path %></td>
  </tr>
<% end %>
</table>

It looks like that the data entered in SQLite do not sync with rails. Do you have any idea what I have done wrong and how I can fix it?

Thank you.

thank_you
  • 11,001
  • 19
  • 101
  • 185
Ron
  • 69
  • 2
  • 7
  • Make sure that you have an association between your `Home` and the `Image` model, if you unsure about how to link the two, I would recommend for you to start by reviewing this: http://guides.rubyonrails.org/association_basics.html – fmendez Mar 22 '13 at 02:11
  • I think running through this tutorial will help you. http://ruby.railstutorial.org/ruby-on-rails-tutorial-book – thank_you Mar 23 '13 at 00:31

4 Answers4

0

What's happening is that you are looping through a selection of records from the Home table. Because of this, when you call

<td><%= home.image_path %></td>

it's not recognizing the attribute image_path because you don't have image_path as a column of Home table. You only have Home_ID, Home_Name, Admin_ID for your columns. You will have to look into associations between models in order to figure out how to grab the image_path for each home record. You can start here.

If you update the code later on I'll be glad to comment on it.

thank_you
  • 11,001
  • 19
  • 101
  • 185
  • Thanks Jason, I was looking at the association basics before, but couldn`t really figure out how to apply it to my projects. I will post the codes I have below and I would be very happy if you could have a look. Sorry for my silly questions. I only started a few weeks ago and many things are still too abstract to me. – Ron Mar 22 '13 at 23:23
  • I also created a _form under views/images/ `<%= form_for(@image) do |f| %> <% if @image.errors.any? %>

    <%= pluralize(@image.errors.count, "error") %> prohibited this image from being saved:

      <% @image.errors.full_messages.each do |msg| %>
    • <%= msg %>
    • <% end %>
    <% end %>
    – Ron Mar 23 '13 at 00:04
  • `
    <%= f.label :image_name %>
    <%= f.text_field :image_name %>
    <%= f.label :image_path %>
    <%= f.text_field :image_path %>
    <%= f.label :image_description %>
    <%= f.text_area :image_description %>
    <%= f.submit %>
    <% end %>`
    – Ron Mar 23 '13 at 00:04
  • Best to post this code to your question since it will be easier to read. I should also note that it sounds like the project you want is not just for kicks. I highly suggest you do smaller projects before tackling something like this. – thank_you Mar 23 '13 at 00:21
  • Thanks Jason, the guide helped me a lot and I was able to get it work. :) – Ron Mar 26 '13 at 22:05
  • @Ron Great! As a note remember to check the question that answered your question, whether that be another user's or your answer updated with the correct code. Best of luck to you. – thank_you Mar 26 '13 at 22:15
0

I'm not positive what the relationship would be between your images and home models would be so correct me if I'm wrong, but I'm guessing that homes will have many images. Each image would belong to one home. Is this correct? If so, you will need to declare that in your models like so:

models/home.rb

has_many :images

models/image.rb

belongs_to :home

You will then need to add this to the image database:

t.integer  "home_id"

You can add it by going to the command line and typing:

rails g migration AddHomeToImages home_id:integer

You should look in db/migrate/ and then the most recent migration file and make sure it looks like this:

add_column :images, :home_id, :integer

Then run:

rake db:migrate

At this point you'll only need to update your controller and views to show this association. Let me know if this helps and if so I'll help you with your controller and views.

lflores
  • 3,770
  • 3
  • 19
  • 24
  • Many thanks for that. I have done it, but cannot figure how to put the association between the controller and views. So far I have: **home.rb** `class Home < ActiveRecord::Base attr_accessible :address, :admin_id, :details, :name, :price, :region has_many :images end` **image.rb** `class Image < ActiveRecord::Base attr_accessible :image_description, :image_name, :image_path belongs_to :home end` and the index.html.erb from my first post. All attempts to link them ran into error. – Ron Mar 22 '13 at 22:00
  • I think it is important to know that I would like to have a template where there is one main image on top and below 3 smaller images. Below these 4 images should be the description of the home. Do you know any tutorials where it is explained on how to do it? I checked the first 3 pages of Google`s results, but couldn't find anything like that ... or too advanced for me. – Ron Mar 22 '13 at 22:07
  • What's the error you received from your models? Posting it in your question will help us know the problem. – thank_you Mar 23 '13 at 00:23
  • Hi Jason, I have added the error message and the code. Hope it will be sufficient. Many thanks. – Ron Mar 24 '13 at 22:56
0

I think that the best solution here will be to use paperclip gem. You can take a look at this very old railscast eoisode just to understand how it works:

http://railscasts.com/episodes/134-paperclip

And here is github repository:

https://github.com/thoughtbot/paperclip

Paperclip will help you with paths, styles and preview for your images.

  • Thanks Mosin, I checked the video and it is pretty cool stuff, but is it possible to add more than one picture using paperclip? I assume so, but how can I link the image_id`s to the right image div in my template? – Ron Mar 22 '13 at 22:47
  • 1
    Paperclip is great and awesome, but I would suggest you learn it without the paperclip gem first. You have to learn the basics before using gems. – thank_you Mar 23 '13 at 00:26
0

Thanks Jason,

I agree that it is a bit big for newbies, but the requirements were that we do a website where we need to read and write from/to a database. We had a quick introduction to rails with partnerwork and are now on our own and a "bit" lost and running out of time.

Here is the error message I am getting:

NameError in Homes#index

undefined local variable or method `image' for

<#:0xb62f7aa4>

Extracted source (around line #20):

17: <% @homes.each do |home| %>
18:   <tr>
19:     <td><%= home.name %></td>
20:     <td><%= image.home_id %></td>
21:     <td><%= home.details %></td>
22:     <td><%= home.region %></td>
23:     <td><%= home.address %></td>

When I create the database tables I had an Image_ID in the homes table, but I was told that I don`t need it and that it is enough to have only Home_ID in the images table.

I understand that the error is caused because of image.home_id. What is your opinion? Should I add the Image_ID back to the homes table in order to display all images for the respective home_id or is there another way? I would like to be able to decide which picture will be displayed as the main picture and which ones as the smaller pictures.

Here is the code I use:

models/home.rb

class Home < ActiveRecord::Base
  attr_accessible :address, :admin_id, :details, :name, :price, :region

  has_many :images

end

models/image.rb

class Image < ActiveRecord::Base
  attr_accessible :image_description, :image_name, :image_path

  belongs_to :home  

end

views/homes/index.html.erb

<h1>Listing homes</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Image</th>
    <th>Details</th>
    <th>Region</th>
    <th>Address</th>
    <th>Price</th>
    <th>Admin</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @homes.each do |home| %>
  <tr>
    <td><%= home.name %></td>
    <td><%= image.home_id %></td>
    <td><%= home.details %></td>
    <td><%= home.region %></td>
    <td><%= home.address %></td>
    <td><%= home.price %></td>
    <td><%= home.admin_id %></td>
    <td><%= link_to 'Show', home %></td>
    <td><%= link_to 'Edit', edit_home_path(home) %></td>
    <td><%= link_to 'Destroy', home, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Home', new_home_path %>

views/homes/show.html.erb

<p id="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @home.name %>
</p>

<p>
  <b>Image:</b>
  <%= @image.home_id %>
</p>

<p>
  <b>Details:</b>
  <%= @home.details %>
</p>

<p>
  <b>Region:</b>
  <%= @home.region %>
</p>

<p>
  <b>Address:</b>
  <%= @home.address %>
</p>

<p>
  <b>Price:</b>
  <%= @home.price %>
</p>

<p>
  <b>Admin:</b>
  <%= @home.admin_id %>
</p>


<%= link_to 'Edit', edit_home_path(@home) %> |
<%= link_to 'Back', homes_path %>

views/images/_form.html.erb

<%= form_for(@image) do |f| %>
  <% if @image.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@image.errors.count, "error") %> prohibited this image from being saved:</h2>

      <ul>
      <% @image.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :image_name %><br />
    <%= f.text_field :image_name %>
  </div>
  <div class="field">
    <%= f.label :image_path %><br />
    <%= f.text_field :image_path %>
  </div>
  <div class="field">
    <%= f.label :image_description %><br />
    <%= f.text_area :image_description %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

controllers/images_controller.rb

class ImagesController < ApplicationController
  # GET /images
  # GET /images.json
  def index
    @images = Image.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @images }
    end
  end

  # GET /images/1
  # GET /images/1.json
  def show
    @image = Image.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @image }
    end
  end

  # GET /images/new
  # GET /images/new.json
  def new
    @image = Image.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @image }
    end
  end

  # GET /images/1/edit
  def edit
    @image = Image.find(params[:id])
  end

  # POST /images
  # POST /images.json
  def create
    @image = Image.new(params[:image])

    respond_to do |format|
      if @image.save
        format.html { redirect_to @image, notice: 'Image was successfully created.' }
        format.json { render json: @image, status: :created, location: @image }
      else
        format.html { render action: "new" }
        format.json { render json: @image.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /images/1
  # PUT /images/1.json
  def update
    @image = Image.find(params[:id])

    respond_to do |format|
      if @image.update_attributes(params[:image])
        format.html { redirect_to @image, notice: 'Image was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @image.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /images/1
  # DELETE /images/1.json
  def destroy
    @image = Image.find(params[:id])
    @image.destroy

    respond_to do |format|
      format.html { redirect_to images_url }
      format.json { head :no_content }
    end
  end
end

Thank you so much. I really appreciate your help!!!

Ron
  • 69
  • 2
  • 7