RoR:我怎样才能搜索某种微博(数据库表)?

时间:2012-09-25 19:33:46

标签: ruby ruby-on-rails-3

现在我有一个名为Microposts的对象(我认为)。它是数据库中的一个表,其中有一个名为kind的列。这可以是“购买”或“销售”。在主页上,我列出了每个用户微博分成两个列表。一个只有销售微博,另一个只购买微博。我试图在每个列表的顶部放置一个搜索栏,只能搜索那些列表。然后,当用户搜索时,该列显示搜索结果。

问题在于,我找到的所有教程如http://railscasts.com/episodes/37-simple-search-form?autoplay=true都会介绍如何使用自己的控制器搜索对象(例如,如果我想搜索微博)。我怎样才能搜索购买的微博。或者只搜索销售的那些?

编辑:澄清

以下是我应该在app / views / home.html.erb

中添加的内容
<% form_tag microposts_path, :method => 'get' do %>
  <p>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag "Search", :name => nil %>
  </p>
<% end %>

但我想要的是其中两个,一个搜索所有类型的微博(种类是微博表中的一列)购买,一个搜索所有具有类型销售的微博。我不知道这个的正确语法。

此外,这是我的microposts_controller.rb的相关部分

  def home


    @microposts=Micropost.all

    @purchases=@microposts.collect{ |m| m if m.kind == "purchase"}.compact
    @sales=@microposts.collect{ |m| m if m.kind == "sale"}.compact

  end

编辑2:

你们都有很好的建议来定义@microposts,@purchases和@sales。我认为使用范围是可行的方法。但是,我仍然没有看到这是如何回答这一特定问题的。如何区分这两种搜索表单和搜索定义,以便搜索所有具有销售类型的微博,并通过所有微博搜索所购买的类型。我希望搜索完全不同。我可以以某种方式识别搜索表单吗?如何在模型中以不同方式定义销售搜索和购买搜索。我知道我应该有像

这样的东西
def self.search(search)
  if search
    find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
  else
    find(:all)
  end
end

在micropost.rb中。我是否需要一个购买定义和一个销售定义?

再次编辑:

我试图在RoR: how can I search only microposts with a certain attribute?

更清楚地说明这个问题

3 个答案:

答案 0 :(得分:1)

我会从模型开始

class Micropost < ActiveRecord::Base

  ...
  scope :purchases, where(:kind => 'purchase')
  scope :sales, where(:kind => 'sale')
  ...

现在,您可以使用Micropost.purchasesMicropost.sales,并根据搜索条件的需要添加更多.where,例如

@sales = Micropost.sales.where('name like ?',params[:name])
@purchases= Micropost.purchases.where('name like ?',params[:name])

在您的视图中,您将有两个列表来显示@purchases和@sales,例如:

<%-    @purchases.each do |one_purchase} %>
<%=      one_purchase.name %>
%br
<%-    end %>

<%-    @sales.each do |one_purchase} %>
<%=      one_purchase.name %>
%br
<%-    end %>

答案 1 :(得分:0)

如果你想搜索表格,我会推荐DataTables,一个jQuery插件。它可以让你做你想做的事。此外,它还会进行动态过滤。

答案 2 :(得分:0)

您应该在ActiveRecord Query Interface上阅读本指南,但这是您问题的答案:

@purchases = Micropost.where(['`microposts`.kind = ?', 'purchase'])
@sales = Micropost.where(['`microposts`.kind = ?', 'sale'])

您也可以设置范围。

关于搜索,我建议ThinkingSphinx作为一个简单,轻量级的解决方案:

您可以设置micropost范围和索引,如下所示:

class Micropost < ActiveRecord::Base

  # ...

  scope :purchases, where(:kind => 'purchase')
  scope :sales, where(:kind => 'sale')

  # Here you can define which columns are searchable.

  define_index do
    indexes :name
  end

  # You can even search based on associations, but this is even more complicated
  # and outside the scope of this question. My point: It's very adapatable..

  # Using a sphinx_scope..
  sphinx_scope(:by_kind) { |kind| { :conditions => { :kind => kind } } }

end

通过ThinkingSphinx,使用sphinx引擎非常简单。在您的控制器中,例如:

def search
  @microposts = Micropost.search(params[:query]).compact

  respond_to do |format|
    format.html
  end
end

# Or, using the sphinx_scope:
# Assumes params[:kind] contains either 'sale' or 'purchase'
def search_by_kind
  @microposts = Micropost.by_kind(params[:kind]).search(params[:query]).compact

  respond_to do |format|
    format.html
  end
end

以你的形式......

<select id="select_kind" name="kind">
  <option value="purchase" selected="selected">Purchase</option>
  <option value="sale">Sale</option>
</select>

..将转换为params[:kind] ..