そこで、私は教育リソース検索エンジンRailsアプリを構築しています。このアプリは、 Isotopeを活用することを目的としたブロックタイプのレイアウトで結果(たとえば、Calculusビデオ)を表示します(クールなフィルタリング/ソート遷移など)。
適切なリソースについてデータベースにクエリを実行することに加えて、カスタム検索エンジンAPIを介してGoogleにもクエリを実行しています。その上、最終的にはいくつかの広告ブロックをグリッドビューに配置する必要があります。
だから私の質問は、データベースのクエリから返された@resourcesをGoogleクエリのJSON結果と、そして最終的には広告とどのように組み合わせることができるかということです。結果ビュー(search.html.erb)をできるだけきれいにするためにこれを実行したいと思います。さらに、すべての結果を並べ替え/フィルタリングできるようにしたいと思います。つまり、ActiveRecordの結果をGoogleのクエリ結果とマージできるようにしたいと思います。これにより、次のようなこともできます。
(Boxxは私が考えているジェネリッククラスです)
<% @boxxes.each do |boxx| %>
<div class=<%= boxx.type %>>
<h2><%= boxx.title %></h2>
<h3><%= boxx.description %></h3>
...
...
...
</div>
<% end %>
私のリソースコントローラーは以下のとおりです。基本的に、@ resourceとGoogleクエリの結果を組み合わせて、共通のインターフェイスを備えた列挙可能なものにし、ユーザーが指定した並べ替えの種類に従って並べ替えることができます。
これを行うための最良の方法は何ですか?コントローラの下部にBoxxクラスを作成し、Resource、google JSON、またはAdのいずれかで初期化できるようにする必要がありますか?次に、型変数を保持して、それらをすべて一緒に並べ替えることができますか?
これが私のリソースコントローラーです
require 'will_paginate/array'
class ResourcesController < ApplicationController
def index
@resources = Resource.all
end
def create
# Usability concern here... need to make sure that they are redirected back here once they log in or something
if current_user == nil
flash[:alert] = "You must log in to submit a resource!"
redirect_to resources_path
return
else
params[:resource][:user_id] = current_user.id
end
# Check to see if this resource unique
params[:resource][:link] = Post::URI.clean(params[:resource][:link])
if unique_link?(params[:resource][:link])
@resource = Resource.new(params[:resource])
@resource[:youtubeID] = self.isYoutube(@resource[:link])
@resource.save
else
flash[:alert] = "This resource has already been added!"
end
redirect_to resources_path
end
def vote
value = params[:type] == "up" ? 1 : -1
@resource = Resource.find(params[:id])
@resource.add_or_update_evaluation(:votes, value, current_user)
respond_to do |format|
format.html { redirect_to :back, notice: "Thank you for voting" }
format.json { render :status=>200, :json=>{:success=>true}}
end
end
def isYoutube(youtube_url)
regex = %r{http://www.youtube.com}
if youtube_url[regex]
youtube_url[/^.*((v\/)|(embed\/)|(watch\?))\??v?=?([^\&\?]*).*/]
youtube_id = $5
thumbnail_Link = "http://img.youtube.com/vi/#{youtube_id}/1.jpg"
else
thumbnail_Link = nil
end
thumbnail_Link
end
def unique_link?(url)
Resource.find_by_link(url) == nil
end
def search
@resource = Resource.full_search(params[:q])
# raise params.to_s
@resource = @resource.reject!{|r| !r.media_type.eql? params[:filter][0][:media_type].downcase } if params[:filter] && !params[:filter][0][:media_type].blank?
if params[:filter]
case params[:filter][0][:sort].downcase
when 'newest'
then @resource = @resource.sort_by{|r| r.created_at}
when 'votes'
then @resource = @resource.sort_by!{|r| r.reputation_for(:votes).to_i}.reverse
else
end
end
@resource = @resource.paginate(:page => (params[:page] || 1), :per_page => 15)
end
def google(q, filter)
# Authenticating into Google's API
client = Google::APIClient.new(:key => 'secret', :authorization => nil)
# Discover the Custom Search API
search = client.discovered_api('customsearch')
# Search Google CSE
response = client.execute(
:api_method => search.cse.list,
:parameters => {
'q' => "#{q} #{filter}",
'key' => 'secret',
'cx' => 'secret'
}
)
# Decode the results
results = ActiveSupport::JSON.decode(response.body, {:symbolize_names => true})
# Return an empty array if Google CSE limit has been met.
results["items"] == nil ? [] : results["items"]
end
def make_boxxes(resources, google_results, ads)
end
end
編集#1:待って、GoogleResultクラスを作成してから、
@items = @resources | google_results
?
GoogleResultをResourcesと同じインターフェースに従わせることができたからです。しかし、どうすればそれらを並べ替えることができますか?うーん...