Ruby/Rails 1&2:收集问题
嘿,我刚刚开始学习 ruby/rails。 目前,我尝试做一本德语书“Praxiswissen Ruby on Rails”的示例,这本书很老了,是为 Ruby on Rails 1 编写的。无论如何,我尝试用 Rails 2 做示例。现在我遇到了问题一个多星期了。
根据书(Rails 1)我必须在我的控制器中编写:
页面.replace_html( '广播搜索结果', :部分=> '广播搜索结果', :收藏=> @视频['项目'] );
我发现 Rails 2 中的写法类似于:
@items = 尝试(@videos[:items])
页面.replace_html( '广播搜索结果', :部分=> @项目 )
但是服务器抛出以下消息:
ActionView::MissingTemplate(视图路径 app/views 中缺少模板 hashes/_hash.erb):
app/controllers/stations_controller.rb:46:在`__instance_exec0'中
app/controllers/stations_controller.rb:30:在“search_broadcasts”中
我应该创建模板 hashes/_hash.erb 而不是 station/_item.erb。 有人可以帮我吗?
非常感谢!
好的,我将添加控制器代码: station_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ü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
模型broadcast.rb(用于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
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ü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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您看到的问题似乎是,当 Rails 尝试渲染对象的部分时,它将默认使用该对象的类名作为部分的名称。 data[:items] 中的每个单独项目都是一个哈希,因此在某些时候您尝试渲染其中一个项目,而 Rails 正在寻找 _hash.html.erb 模板。 我认为您想要将以下代码更改
为
:这应该为 @items 中的每个项目呈现 _item.html.erb 部分。
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:
to:
This should render the _item.html.erb partial for each item in @items.