views:

686

answers:

1

Hey, I just began to learn ruby/rails. At the moment, I try to do an example of a german book "Praxiswissen Ruby on Rails", which is pretty old and written for Ruby on Rails 1. Anyway, I tried to do the examples with Rails 2. Now I have had problem for over a week.

According to the book (Rails 1) I have to write in my controller:

page.replace_html( 'broadcast_search_result', :partial => 'broadcast_search_result', :collection => @videos['items'] );

I found out that this in Rails 2 is written similar to that:

@items = try(@videos[:items])

page.replace_html( 'broadcast_search_results', :partial => @items )

But the server throws following message:

ActionView::MissingTemplate (Missing template hashes/_hash.erb in view path app/views):

app/controllers/stations_controller.rb:46:in `__instance_exec0'

app/controllers/stations_controller.rb:30:in `search_broadcasts'

I should create a template hashes/_hash.erb instead of stations/_item.erb. Can anybody help me, please?

Thank you very much!


OK, I'll add the controller code: stations_controller.rb:

class StationsController < ApplicationController
  # GET /stations
  # GET /stations.xml
  def index
    @stations = Station.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @stations }
    end
  end

  #GET /stations/search_broadcasts
  def search_broadcasts
    @search = params[:broadcast_search][:search]
    @channel = params[:broadcast_search][:channel]
    if params[:broadcast_search][:current_page]
      @current_page = params[:broadcast_search][:current_page].to_i
    else
      @current_page = 1
    end

    @videos = Broadcast.get_videos(
      @search,
      @channel,
      2,
      @current_page
    )

    render(:update) { |page|
      if @videos[:http_code] == 200
        page.replace_html(
          'broadcast_search_results_count',
          :inline => "<p>Es wurden <b><%= @videos[:count] %></b> Sendung<%= 'en' unless @videos[:count] == 1 %> gefunden</p>"
        )
      else
        page.replace_html(
          'broadcast_search_results_count',
          :inline => "<p>Es trat ein Fehler bei der Daten&uuml;bertragung auf.</p>"
        )
      end

      if @videos[:count] > 0
        logger.debug "The object is #{@videos[:items]}"
        @items = @videos[:items]
        page.replace_html(
          'broadcast_search_results',
          :partial => @items
        )
        page.replace_html(
          'broadcast_search_results_navigation',
          :partial => 'broadcast_search_results_navigation',
          :locals => {
            :videos => @videos,
            :search => @search,
            :channel => @channel,
            :current_page => @current_page
          }
        )
        page.show('broadcast_search_results')
        page.show('broadcast_search_results_navigation')
        #page.visual_effect(
        #  :highlight,
        #  'bradcast_search_results'
        #)
      else
        #page.hide('broadcast_search_results')
        #page.hide('broadcast_search_results_navigation')
      end
    }
  end

  # GET /stations/1
  # GET /stations/1.xml
  def show
    @station = Station.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @station }
    end
  end

  # GET /stations/new
  # GET /stations/new.xml
  def new
    @station = Station.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @station }
    end
  end

  # GET /stations/1/edit
  def edit
    @station = Station.find(params[:id])
  end

  # POST /stations
  # POST /stations.xml
  def create
    @station = Station.new(params[:station])

    respond_to do |format|
      if @station.save
        flash[:notice] = 'Station was successfully created.'
        format.html { redirect_to(@station) }
        format.xml  { render :xml => @station, :status => :created, :location => @station }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @station.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /stations/1
  # PUT /stations/1.xml
  def update
    @station = Station.find(params[:id])

    respond_to do |format|
      if @station.update_attributes(params[:station])
        flash[:notice] = 'Station was successfully updated.'
        format.html { redirect_to(@station) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @station.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /stations/1
  # DELETE /stations/1.xml
  def destroy
    @station = Station.find(params[:id])
    @station.destroy

    respond_to do |format|
      format.html { redirect_to(stations_url) }
      format.xml  { head :ok }
    end
  end
end

The model broadcast.rb (for Broadcast.get_videos):

require('net/http')
require('uri')
require('xmlsimple')

class Broadcast < ActiveRecord::Base
  belongs_to :station

  AOL_API_URL = 'http://xml.truveo.com/apiv3'
  AOL_DEVELOPER_ID = '12345667myid'

  def self.channels
    return[
      '[Alle Quellen]',
      'YouTube',
      'MYSPACE',
      'Dailymotion',
      'Google Video',
      'IFILM',
      'Veoh'
    ]
  end

  def self.get_videos(search, channel, per_page, page)

    channels = '' if channel == '[Alle Quellen]'

    url = AOL_API_URL +
      "?method=truveo.videos.getVideos" +
      "&query=" + URI.escape("#{search} type:free format:flash channel:\"#{channel}\"") +
      "&results=#{per_page.to_i}" +
      "&start=#{(page.to_i) * per_page.to_i}" +
      "&appid=#{AOL_DEVELOPER_ID}"
    data = Broadcast.get_xml(url)

    if data[:http_code] == 200
      data[:page_count] = data[:count] / per_page
      data[:page_count] += 1 if data[:count] % per_page > 0
    end

    return data
  end

  def self.get_video(video_id)
    url = AOL_API_URL +
    "?method=truveo.videos.getVideos" +
    "&query=" + URI.escape('id:' + video_id.to_s) +
    "&appid=#{AOL_DEVELOPER_ID}"
    data = Broadcast.get_xml(url)

    video = data[:items][0]
    video[:http_code] = data[:http_code]
    return video
  end

  def self.get_xml(url)

    # Data-Objekt initialisieren
    data = Hash.new
    data[:count] = 0
    data[:items] = Array.new
    data[:url] = url

    # XML-Daten holen
    xml = Net::HTTP.get_response(URI.parse(url))

    # HTTP-Response-Code ŸberprŸfen
    data[:http_code] = xml.code.to_i
    return data unless data[:http_code] == 200

    # XML Parsen
    xml_obj = XmlSimple.xml_in(xml.body.to_s)
    data[:count] = xml_obj['VideoSet'][0]['totalResultsAvailable'][0].to_i
    return data if data[:count] == 0

    # Informationen auslesen
    xml_obj['VideoSet'][0]['Video'].each { |xml_video|
      new_video = Hash.new
      new_video[:video_id] = xml_video['id'][0].to_s
      new_video[:title] = xml_video['title'][0].to_s
      new_video[:source_url] = xml_video['videoUrl'][0].to_s
      new_video[:thumbnail_url] = xml_video['thumbnailUrl'][0].to_s
      new_video[:description] = (xml_video['description'][0].to_s) if xml_video['description']
      new_video[:video_html] = (xml_video['videoPlayerEmbedTag'][0].to_s) if xml_video['videoPlayerEmbedTag']
      data[:items] << new_video
    }

    return data

 end

end
+1  A: 

It appears that the problem you're seeing is that when Rails attempts to render a partial for an object, it will default to using that object's class name as the name for the partial. Each individual item in data[:items] is a Hash, so at some point you're attempting to render one of those items and Rails is looking for a _hash.html.erb template. I think you want to change the following code:

page.replace_html(
  'broadcast_search_results',
  :partial => @items
)

to:

page.replace_html(
  'broadcast_search_results',
  :partial => 'item',
  :collection => @items
)

This should render the _item.html.erb partial for each item in @items.

Greg Campbell
Thank you very much! I don't know why, but that was exactly the solution of the book... Now the view is right, but it doesn't renders anything, anyway. The called div is empty.
alife
OK I am happy now. In my partial I typed thumbnail_url, but it is item[:thumbnail_url]. Thank you very much!
alife