Rails,简单搜索带有act-as-taggable-on gem的视频对象标签

时间:2016-10-25 15:53:17

标签: ruby-on-rails search tags acts-as-taggable-on

的routes.rb

resources :videos, except: [:create, :update] do
  collection do
    get "/search", to: "videos#search", as: "search"
  end
  resources :comments, except: [:show, :index]
end

模型/ video.rb

def self.search(search)
  if search
    find(:all, conditions: ['tag LIKE ?', "%#{search}%"])
  else
    find(:all)
  end
end

videos_controller.rb

def search
  @results = Video.search(params[:search])
end

index.html.erb

<div class="">
  <%= form_tag search_videos_path, method: 'get' do %>
    <%= label_tag(:search, "Search") %>
    <%= text_field_tag :search, "Search by video tag", params[:search] %>
    <%= submit_tag "Search", name: nil %>
  <% end %>
</div>

Rails返回...

undefined method `stringify_keys' for nil:NilClass 

加载视频索引页面时,突出显示此行...

<%= text_field_tag :search, "Search by video tag", params[:search] %>

我还尝试将搜索指向视频控制器索引方法并在其中包含逻辑和@results。

act-as-taggable-on gem为每个视频提供一个标签数组,每个标签都是一个字符串。我正在尝试根据视频索引中的标记搜索视频。我不确定我做错了什么。任何帮助将不胜感激。如果我忘记发布任何可能通知答案的相关代码,请告诉我。谢谢!

3 个答案:

答案 0 :(得分:0)

我相信你想要这个。

<%= text_field_tag :search, params[:search] %>

文字&#34;按视频标记搜索&#34;用于标签标签,在此之外。您可能打算添加占位符选项

<%= text_field_tag :search, params[:search], :placeholder => "Search by video tag" %>

此外,而不是:

find(:all, conditions: ['tag LIKE ?', "%#{search}%"])

你可以这样做

tagged_with(search, :parse => true)

如果标记使用分隔符并在列表上执行OR,则将解析和拆分标记。您可以在传递给tagged_with方法的选项哈希中控制它。

答案 1 :(得分:0)

正如Swards建议的那样,删除占位符文本有助于搜索仍无法正常运行。这是最终工作的......

videos_controller.rb

  def search
    if params[:search]
      @results = Video.tagged_with(params[:search])
    end
  end

的观点/视频/ _search_form.html.erb

<%= form_tag search_videos_path, method: 'get' do %>
  <%= label_tag(:search, "Search") %>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag "Search", name: nil %>
<% end %>

我完全删除了#models / video.rb中的上述代码,现在看起来像这样......

模型/ video.rb

class Video < ActiveRecord::Base
  after_create { validates_presence_of :user, :post }

  belongs_to :user
  belongs_to :post
  has_many :comments

  validates :title, presence: true
  acts_as_taggable
end

答案 2 :(得分:0)

看起来您已从多个来源获得帮助。让我们看看我们是否可以清理一下:

1搜索结果

搜索有两种方法,a。)在您已有的索引页面中显示结果,或b。)创建新路线,以便网址显示&#34; / search&#34;如果用户愿意,用户可以加入书签 - 我更喜欢索引方法,但你可以这样做。要使用索引方法,请删除搜索路径并将控制器更改为:

def index
  @videos = params[:search].nil? ? Video.all : Video.search(params[:search])
end

您还需要将表单的路径从videos_path更改为search_videos_path - 这样您只需使用一个模板即可。如果你想继续将搜索作为自己的控制器,动作,这也很完美。 Rour route和contoller可以保持原样。

2模型搜索

您实际上并未搜索视频表 - 您需要搜索标记表。宝石有一个方法,它被称为tagged_with。您还需要添加else语句,因为您只想返回搜索结果。因此,请将模型更新为:

  def self.search(search)
    videos = Video.tagged_with("#{search}", :any => true)
    return videos
  end

3使搜索文本成为占位符

更改您的表单,使其不使用文字&#34;按视频标记搜索&#34; - 但是这是一个占位符(因此用户在开始输入之前不必删除它)。此外,您不需要包含以前的结果,这取决于您。如果你确实想要它们,你需要说search: params[:search]

  <%= form_tag search_videos_path, method: 'get' do %>
    <%= label_tag(:search, "Search") %>
    <%= text_field_tag :search, "", placeholder: "Search by video tag" %>
    <%= submit_tag "Search", name: nil %>
  <% end %>