Tire と ElasticSearch を使用して検索している Posts と Channels の 2 つのモデルがあります。
現在、すべて正常に動作しています。ただし、2 つの検索を実行し、両方の結果を返しています。これを 1 つに統合して、両方のモデルを同時に検索したいと考えています。
以下は、これを行うために使用しているコントローラー アクションです。
def browse
@user = current_user
@channels = Channel.search(params)
@posts = Post.search(params)
end
以下は Post モデルです。
class Post < ActiveRecord::Base
attr_accessible :description, :name, :tag_list, :thumbnail_image, :status, :post_type, :subtitle, :summary, :visibility, :user
acts_as_taggable
has_one :publication
has_one :user, :through => :publication
has_many :subscriptions, dependent: :destroy
has_many :channel_post_connections, dependent: :destroy
has_many :channels, :through => :channel_post_connections
accepts_nested_attributes_for :channel_post_connections
accepts_nested_attributes_for :channels
accepts_nested_attributes_for :publication
accepts_nested_attributes_for :user
has_many :post_pages, dependent: :destroy
validates_presence_of :post_type, :name, :subtitle, :tag_list, :summary, :thumbnail_image, :if => :post_is_published?
include Tire::Model::Search
include Tire::Model::Callbacks
index_name 'posts_index'
def self.search(params)
tire.search(load: true) do
query { string params[:query], default_operator: "AND" } if params[:query].present?
sort { by :created_at, "desc" } if params[:query].blank?
end
end
def to_indexed_json
to_json(methods: [:user_first_name, :user_display_name])
end
def user_first_name
self.user.first_name if self.user.present?
end
def user_display_name
self.user.display_name if self.user.present?
end
end
以下はチャネル モデルです。
class Channel < ActiveRecord::Base
attr_accessible :title, :description, :cover_image, :status, :writable, :visibility, :thumbnail_image
has_one :channel_publication
has_one :user, :through => :channel_publication
has_many :channel_subscriptions
has_many :channel_post_connections
accepts_nested_attributes_for :channel_publication
accepts_nested_attributes_for :user
mount_uploader :thumbnail_image, ChannelThumbnailImageUploader
include Tire::Model::Search
include Tire::Model::Callbacks
index_name 'channels_index'
def self.search(params)
tire.search(load: true) do
query { string params[:query], default_operator: "AND" } if params[:query].present?
sort { by :created_at, "desc" } if params[:query].blank?
end
end
def to_indexed_json
to_json(methods: [:user_first_name, :user_display_name])
end
def user_first_name
self.user.first_name if self.user.present?
end
def user_display_name
self.user.display_name if self.user.present?
end
end
次に、私の見解では、2 つのループがあります。
- @posts.each do |post|
%h3
= post.name
- @channels.each do |channel|
%h3
= channel.title
繰り返しますが、私の目標は、1 回の検索を実行し、1 回のループを使用してごちゃまぜになった投稿とチャンネルの結果を表示することです。
どんな助けでも大歓迎です...私はこれで髪を引っ張っています!
アップデート
アプリのトレースを追加しています...
app/controllers/posts_controller.rb:111:in `[]'
app/controllers/posts_controller.rb:111:in `block in browse'
app/controllers/posts_controller.rb:110:in `browse'
答え
コントローラーの参照アクションを次のように置き換えました。
def browse
@user = current_user
@search_items = Tire.search(['posts_index', 'channels_index'],{load: true}) do |search|
if params[:query].present?
search.query do |q|
q.string params[:query], default_operator: "AND"
end
end
search.sort { by :created_at, "desc" }
end
@results = @search_items.results
end
そして、ビュー内の @results をループして、うまくいきました!