RoR: how can I search only microposts with a specific attribute?

余生长醉 提交于 2019-12-13 22:01:58

问题


Right now in app/views/microposts/home.html.erb I have..

<% form_tag purchases_path, :method => 'get', :id => "products_search" do %>
  <p>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag "Search", :name => nil %>
  </p>
<% end %>

<% form_tag sales_path, :method => 'get', :id => "sales_search" do %>
      <p>
        <%= text_field_tag :search, params[:search] %>
        <%= submit_tag "Search", :name => nil %>
      </p>
    <% end %>

and then in micropost.rb I have

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

 def self.search(search)
    if search
      where('name LIKE ?', "%#{search}%")
    else
      scoped
    end
  end

and then finally in the microposts_controller.rb I have

    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

edit:

I also tried using

def home

    @microposts=Micropost.all
    @purchases=@microposts.purchases
    @sales=@microposts.sales

  end

instead but then it gives me the error undefined method `purchases' for #

Anways,

Right now with the .collect method I am getting an error saying undefined local variable or method `purchases_path' and it does the same for sales_path.

What I want is to have TWO search forms. In my micropost table I have a column called kind which can be either "purchase" or "sale". How can I change my code so that one search form searches through and displays results for only those microposts with the kind "purchase". And then the other searches through and displays results for only those microposts with the kind "sale"


回答1:


def home
  @microposts = Micropost.all
  @purchases = Micropost.search("purchase", params[:search])
  @sales = Micropost.search("sale", params[:search])
end

def self.search(kind = nil, search = nil)
  results = self.where(:kind => kind) if kind
  results = self.where('name LIKE ?', "%#{search}%") if name
end



回答2:


Assuming Assuming '/microposts/home' if maped to MictropostsController#home app/views/microposts/home.html.erb

<%= form_tag('/microposts/home', :method => :get) do
 <%= text_field_tag 'kind'%>
 <%= submit_tag 'Search' %>
%>

/app/controllers/microposts_controller.rb

def home
  kind = params[:kind]
  if kind.present?
    # if search parameter passed
    @microposts = Micropost.where(:kind => kind)
  else
    # if search parameter not passed, list all micro post
    @microposts = Micropost.all
  end
end



回答3:


OK, so you have a sales_path and a purchases_path, so I'm going to assume they both lead to a controller with a sales and a purchases action

def sales
  @search = params[:search]
  @microposts = Micropost.search(@search).sales
end

def purchases
  @search = params[:search]
  @microposts = Micropost.search(@search).purchases
end

the Micropost.search method will return a scope. So we'll call either #sales or #purhases on that scope which will append a condition onto the query.

UPDATE

It looks like you want to search for two different kinds of microposts from 1 form.

app/views/home/index.html.erb

<%= form_tag(root_path, :method => :get) do
 <%= text_field_tag 'search'%>
 <%= submit_tag 'Search' %>
%>

app/models/micropost.rb

scope :purchase_or_sale, where("kind IN ?", ["purchase", "sale"])
def self.search(search)
  if search
    where('name LIKE ?', "%#{search}%")
  else
    scoped
  end
end

def purchase?
  kind == "purchase"
end

def sale?
  kind == "sale"
end

/app/controllers/home_controller.rb

def home
  @microposts = Micropost.search(params[:search]).purchase_or_sale
  @purchases = @microposts.select(&:purchase?)
  @sales = @microposts.select(&:sale?)  
end

UPDATE 2

OK, one more update.... Here's what I think you want now: 2 search forms, both the /microposts ... if I search on the sales form, it will show sales. if I search on the purchases form, it will search purchases.

your view:

<%= form_tag(microposts_path(kind: "purchases", :method => :get) do
 <label for="search">Search Purchases:</label>
 <%= text_field_tag 'search' %>
 <%= submit_tag 'Search' %>
%>

<%= form_tag(microposts_path(kind: "sales", :method => :get) do
 <label for="search">Search Sales:</label>
 <%= text_field_tag 'search' %>
 <%= submit_tag 'Search' %>
%>

Your controller:

def index
  @microposts = Micropost.search(params[:search).for_kind(params[:kind])
end

Your model

def self.search(search_text)
  if search_text
    where('name LIKE ?', "%#{search_text}%")
  else
    scoped
  end
end

scope :for_kind, lambda{|search_kind| where(kind: search_kind) }



回答4:


As per your comment on another response:

def home
  @microposts = Micropost.scoped # so you can later apply any scope
  if params[:purchases_search].present?
    @microposts = @microposts.purchases.search(params[:purchases_search])
  elsif params[:sales_search].present?
    @microposts = @microposts.sales.search(params[:sales_search])
  end
end

This assumes that the names of the two search fields are "purchases_search" and "sales_search".




回答5:


Why dont you split the microposts in two new models inheriting the micropost model?

class Micropost < ActiveRecord::Base

  #do your general micropost magic here

end

Next:

class Purchase < Micropost

  #do your purchase specific magic here

end

And:

class Sale < Micropost

  #do your sale specific magic here

end

Your home action:

def home

  @microposts = Micropost.all
  @purchases = Purchase.all
  @sales = Sale.all

end

If you need to search Purchases:

Purchase.where(:something => "great")

If you need to search Sales:

Sale.where(:something => "greater")

If you need to search both:

Micropost.where(:something => "the greatest")

** NOTE ** You need to add a column "type" to the microposts table for this to work, more information: Single table inheritance @ http://api.rubyonrails.org/classes/ActiveRecord/Base.html



来源:https://stackoverflow.com/questions/12575140/ror-how-can-i-search-only-microposts-with-a-specific-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!