Pregunta

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.

¿Fue útil?

Solución

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.

Otros consejos

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.

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 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!!!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top