0

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"

BigBoy1337
  • 4,735
  • 16
  • 70
  • 138
  • Where do you show search results? – Amit Patel Sep 27 '12 at 04:40
  • I am trying to have them show up in the home view. So at first its just two lists, each with a search field above them. One list is all the microposts with the kind "purchase". Then if you use the search field that list turns into the list of search results (still only microposts with the kind "purchase"). The other list/search field is exactly the same but for sale microposts – BigBoy1337 Sep 27 '12 at 12:12

5 Answers5

0
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
ddb
  • 1,416
  • 11
  • 17
  • can you explain this code a little bit more? So the def home goes into the controller and the def self.search goes into the model right? Also, when I try it, It give me an error saying there is no column name, probably because of the if name at the end. – BigBoy1337 Sep 25 '12 at 05:05
  • also, from the def home it looks like it is searching for microposts that have the word "purchase" in them (or the word "sale"). Is this true? – BigBoy1337 Sep 25 '12 at 05:06
  • search method is a function that can take 2 optional parameters - kind and search. if you pass the kind, then it filters by the kind and if you pass the search string, it further filters by name like the search string. – ddb Sep 28 '12 at 04:29
0

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) }
Jesse Wolgamott
  • 40,197
  • 4
  • 83
  • 109
  • no I didn't have those. A large part of my confusion was how to make the purchases_path and sales_path. That didn't fix the error though. Should I define the scopes as well in the the home section of the microposts controller instead of using the .collect method? – BigBoy1337 Sep 27 '12 at 02:46
  • look at my edits to see what I mean for a possible redefinition of purchases and sales in the microposts controller – BigBoy1337 Sep 27 '12 at 02:47
  • also, because I am rendering @ sales and @ purchases in the view, shouldn't I be defining @ purchases and @sales in the purchases_path and sales_path instead of @ microposts? – BigBoy1337 Sep 27 '12 at 03:51
  • Sorry If Im not being clear. I don't want two kinds of micropost searched from one form. I want TWO forms. The first searches one kind of micropost (microposts that have the kind "purchase". kind is a column in the database). The second form searches the other kind of micropost (microposts that have the kind "sale) – BigBoy1337 Sep 27 '12 at 19:57
  • additionally there is no home_controller.rb. There is a microposts_controller.rb. Home is just the name of one of the views (the home page) – BigBoy1337 Sep 27 '12 at 20:00
  • Ok sorry for all the comments. but I have been researching this alot and I think my problem is in sales_path and purchases_path. There is no /sales or /purchases. sales and purchases are both kinds of microposts. Each micropost has a :kind, either "sale" or "purchase". I am trying to find a way to identify this in the search form – BigBoy1337 Sep 28 '12 at 01:10
  • sorry for the delay. It is working until I try and visit the home page. That is where I want the search fields so instead of def index in my controller I put def home. When I do visit the home page after signing in I get undefined method `for_kind' for nil:NilClass – BigBoy1337 Oct 03 '12 at 20:16
  • well I added the scope :for_kind line. Isn't that where it is supposed to be definded in the micropost model? – BigBoy1337 Oct 04 '12 at 00:23
  • Yes, but you likely have something wrong. the for_kind is being executed on the result of the search method --- and it looks like the search method is returning nil. You should add this to a gist.github.com and post the link. This has really gone on way too long. Without a gist, I'm not going to comment further. – Jesse Wolgamott Oct 04 '12 at 12:43
0

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
Amit Patel
  • 15,609
  • 18
  • 68
  • 106
  • ooh this looks really close. The only thing is that I want two search fields. One automatically searches through all microposts with the kind "purchase" and the other searches through all microposts with the kind "sale". (those are the only two possible kinds) How can I change this so that this would be true? – BigBoy1337 Sep 27 '12 at 11:34
  • also just for syntax, shouldn't there be <% end %> at the end of the form_tag? – BigBoy1337 Sep 27 '12 at 11:52
0

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".

rewritten
  • 16,280
  • 2
  • 47
  • 50
0

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

Vikko
  • 1,396
  • 10
  • 23