Hard time with checkboxes

Hi, I’ve been having a heck of a time trying to get checkboxes for
filter options of a search page working. I have a SearchController and
views: index, keyword, for the searching part. And I have the Event
model, controller and views. The Event model contains the actual search
method since I need to search through all Events for the given keyword.
What I need to do is somehow get the Event model to know whether or not
the checkboxes in the Search view index are checked without using a
database. I tried using attr_reader, but it doesn’t work. This is what
I have now:

class Event < ActiveRecord::Base

attr_accessor :search_streams
attr_accessor :search_auds

def self.search(keywords, options = {}, *args)

if @search_streams == "1"
   ...
end

if @search_auds == "1"
   ...
end

end

class SearchController < ApplicationController
def index
@calendars = Calendar.find(:all)
@calendars << default_calendar
end

And in the search index view:

Find events that interest you.

<% form_for :event do |f| %>
<%= f.check_box :search_streams, {:class => ‘check’} %>  Search
Streams

<%= f.check_box :search_auds, {:class => ‘check’} %>   Search
Audiences

<% end %>

Is it even possible to access the checkboxes from the search index in
the Event model? I really need help with this, I’m so confused about
checkboxes… I’m not even sure of how to get whether or not checkboxes
are even checked!

hi again,

ok, there are some misunderstandings:
attr_accessor would allow to generate a kind of virtual attribute for an
object of event.
Since you don’t have one but want to work on the class level, forget
about it for now

check your development.log file for the params you get when submitting
the form.

there should be something like
params[:event][:search_streams]

and it should have a value “0” or “1”

to get them into your search method, just add two params:

def self.search(search_streams, search_auds, keywords, options = {},
*args)

call it with
Event.search(params[:event][:search_streams],
params[:event][:search_auds], …)

by the way: since you checkboxes have (technically) nothing to do with
event objects, there is no real need to use form_for, a simple form_tag
would to (like proposed yesterday)

few details to forms in general, checkboxes in special & the params
hash.

  1. Whatever you submit from a form will end in your params hash
  • this can be accessed in the controller or the view
  • not directly in the model (you can hand it as a methods attribute of
    course)
    the name is always the same as that of the form element.
    so if your checkbox name is “search_streams” you’ll find it’s value in
    params[:search_streams]. This value is always a string. For checkboxes
    that’s a “1” (checked) or “0” (unchecked). These values can be
    configured:

check_box(“puppy”, “gooddog”, {}, “yes”, “no”)

in this case the return value would be “yes” or “no” in
params[:puppy][:gooddog]
But there is no real need to do this in most cases.

The most simple checkbox:

check_box_tag ‘accept’

would return “1” or “0” in params[:accept]
You would use this with form_tag.

If you use form_for Rails will add the object class to the name:

form_for :puppy do |f|
f.checkbox :gooddog
end

will give you params[:puppy][:gooddog]

If in any case you’re unsure, how or what your submit returns, look in
the output in development.log or in the terminal output of your server.
You’ll find a line like this:

Processing LoginsController#edit (for 127.0.0.1 at 2008-05-30 13:47:19)
[GET]
Session ID: 6601a5bbfa26e7d60967710c49a1203720462a22…
Parameters: {“action”=>“edit”, “event”=>{“search_streams”=>“1”,
“search_aud”=>“0”}, “controller”=>“admin/logins”}

You can see the splitted params for event and it’s content, the two
values of your checkbox.

Thorsten M. wrote:

check your development.log file for the params you get when submitting
the form.

there should be something like
params[:event][:search_streams]

and it should have a value “0” or “1”

I’m not seeing anything like this in the log…I just see:

Processing SearchController#index (for 127.0.0.1 at 2008-05-30 09:00:53)
[GET]
Session ID: 47bf040683602f74418e9857e941df1a
Parameters: {“action”=>“index”, “controller”=>“search”}

by the way: since you checkboxes have (technically) nothing to do with
event objects, there is no real need to use form_for, a simple form_tag
would to (like proposed yesterday)

So I would use <%= check_box_tag(“Search Streams”,
“event[search_streams]”) %>? How do I use this with form_tag?

Thanks so much for helping me again, I didn’t think I explained my
problem very well in the last thread so I tried to give a better outline
of it here.

ok, I think it’s best, first to get your form data as params into the
controller and later see, how to use it for search within the model.

I’m not seeing anything like this in the log…I just see:

that helps :slight_smile:

your form:

<% form_for :event do |f| %>
<%= f.check_box :search_streams, {:class => ‘check’} %>  Search
Streams

<%= f.check_box :search_auds, {:class => ‘check’} %>   Search
Audiences

<% end %>

does not have a submit button. So you get to the controller via a link?
Then you’ll never get any params from the form.

The most simple form. Since it’s not providing any attributes for event
a such, I’ll use the form_tag:

<% form_tag(:controller => "search, :action => “index”) do %>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences

<%= submit_tag(‘Search’) %>
<% end %>

This should give you the params in the simple form
params[:search_streams]
(and show up in development.log)

Thorsten M. wrote:

The most simple form. Since it’s not providing any attributes for event
a such, I’ll use the form_tag:

<% form_tag(:controller => "search, :action => “index”) do %>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences

<%= submit_tag(‘Search’) %>
<% end %>

This should give you the params in the simple form
params[:search_streams]
(and show up in development.log)

Okay I now have

<% form_tag(:controller => ‘search’, :action => ‘index’) do %>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences
<%= submit_tag(‘Save Changes’) %>


<% end %>

<% form_tag({:controller => ‘search’, :action => ‘keyword’}, {:method =>
‘post’}) do -%>
<%= text_field_tag ‘text’ -%> <%= submit_tag ‘Search’ -%>

<% end -%>

in my index…and also in my keyword view (shows the results), and I’m
getting Parameters: {“commit”=>“Save Changes”, “action”=>“index”,
“controller”=>“search”, “search_auds”=>“1”, “search_streams”=>“1”}
in my log now like you said i should. But when I don’t click one of the
boxes, it doesn’t put “search_auds” => “0” or anything… is this what’s
supposed to happen?

Also, would I be able to include the checkboxes with the text_field_tag
so that the user doesn’t have to submit their filter preferences
separately from their actual search?

Are the checkboxes even being submitted? lol:

<% form_for :event do |f| %>
<%= f.check_box :search_streams, {:class => ‘check’} %>  Search
Streams

<%= f.check_box :search_auds, {:class => ‘check’} %>   Search
Audiences

<% end %>

<% form_tag({:controller => ‘search’, :action => ‘keyword’}, {:method =>
‘post’}) do -%>
<%= text_field_tag ‘text’ -%> <%= submit_tag ‘Search’ -%>

It looks to me like I have 2 separate forms going on (yay for not
knowing what I’m doing!)… if I used the check_box_tag way instead,
could I place them inside the form_tag and have the ‘Search’ submit_tag
submit the checkboxes?

Okay so I did this:

<% form_tag({:controller => ‘search’, :action => ‘keyword’}, {:method =>
‘post’}) do -%>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences


<%= text_field_tag ‘text’ -%>
<%= submit_tag ‘Search’ -%>

<% end %>

I just put the checkboxes in the text_field’s form (which is the same
just with :method => post, and the action to go to keyword because the
keyword page is the page that shows results for the search). Now I’m
getting “#<ArgumentError: wrong number of arguments (2 for 3)>”. What
arguments is it talking about? I think it has to do with either the
‘keyword’ view or the “:method => ‘post’” (what does that do anyway?)

<% form_tag(:controller => ‘search’, :action => ‘index’) do %>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences
<%= submit_tag(‘Save Changes’) %>


<% end %>

<% form_tag({:controller => ‘search’, :action => ‘keyword’}, {:method =>
‘post’}) do -%>
<%= text_field_tag ‘text’ -%> <%= submit_tag ‘Search’ -%>

<% end -%>

in my index…and also in my keyword view (shows the results), and I’m
getting Parameters: {“commit”=>“Save Changes”, “action”=>“index”,
“controller”=>“search”, “search_auds”=>“1”, “search_streams”=>“1”}
in my log now like you said i should. But when I don’t click one of the
boxes, it doesn’t put “search_auds” => “0” or anything… is this what’s
supposed to happen?

I’m not sure if that’s supposed to be that way, but as long as you get a
“1” if it’s clicked, that’s ok I think, since a test like

params[:search_auds] == “1”

will result to false if params[:search_auds] is nil
So you can go on with that.

Also, would I be able to include the checkboxes with the text_field_tag
so that the user doesn’t have to submit their filter preferences
separately from their actual search?

Sure, but you have to decide for one action as the receiver then, since
you can’t submit to different actions in one go.

<% form_tag(:controller => ‘search’, :action => ‘index’) do %>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences
<%= text_field_tag ‘text’ -%>
<%= submit_tag(‘Save Changes’) %>


<% end %>

This should work.

Amanda … wrote:

Is it even possible to access the checkboxes from the search index in
the Event model? I really need help with this, I’m so confused about
checkboxes… I’m not even sure of how to get whether or not checkboxes
are even checked!

In my experience checkboxes can be a real pain since their submission
appears to be browser-dependent. Generally, I’ve found that if a
checkbox is checked, the name/value pair will be sent just as you’d
expect with any form param. If the box is NOT checked, the item is not
submitted at all. It’s not submitted with a value of “”, it’s just not
submitted. To do a test for checkbox state means your code needs to
assume the checkbox was there on the page and test for its presence in
the form parameter list. If it’s absent from your list, then the
checkbox wasn’t checked.

I made a quick little page that illustrates this using a simple so you can see what happens in your URL bar:

http://railsdotnext.com/checkboxtest.shtml

  • Aaron

Thorsten M. wrote:

This would depend on which line generates this error. (Is it when you
render the view or after submit in the controller?)

if it’s the line with the form_tag, then try this:

<% form_tag(:controller => ‘search’, :action => ‘keyword’) do -%>
or
<% form_tag(:controller => ‘search’, :action => ‘keyword’, :method =>
:post) do -%>

It happens when I try to submit the form

Amanda … wrote:

Okay so I did this:

<% form_tag({:controller => ‘search’, :action => ‘keyword’}, {:method =>
‘post’}) do -%>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences


<%= text_field_tag ‘text’ -%>
<%= submit_tag ‘Search’ -%>

<% end %>

I just put the checkboxes in the text_field’s form (which is the same
just with :method => post, and the action to go to keyword because the
keyword page is the page that shows results for the search). Now I’m
getting “#<ArgumentError: wrong number of arguments (2 for 3)>”. What
arguments is it talking about? I think it has to do with either the
‘keyword’ view or the “:method => ‘post’” (what does that do anyway?)

This would depend on which line generates this error. (Is it when you
render the view or after submit in the controller?)

if it’s the line with the form_tag, then try this:

<% form_tag(:controller => ‘search’, :action => ‘keyword’) do -%>
or
<% form_tag(:controller => ‘search’, :action => ‘keyword’, :method =>
:post) do -%>

you can omit the :method for now, it’s not really important here
there are some ‘verbs’ for methods, that indicate to the server what
kind of action is coming in.

:get should only request pages and not change any data (default, what
you do all the time when requesting a page)
:put should create a new object
:post should update an existing object
:delete should destroy an object

But don’t think about that now, you can sort out those details later.

SearchController

def keyword
params[:search_auds] = “0”
params[:search_streams] = “0”
params[:text]=clean_input(params[:text]) unless params[:text].blank?

@events = Event.search params[:search_streams, :search_auds, :text], 

{“calendars” => @calendars, :status => :approved, :include_expired =>
false, :order => @order, :limit => @limit}
@event_pages = Paginator.new self, @events.size, 15, params[:page]
@user_events =
@events[@event_pages.current.offset…@event_pages.current.offset+@event_pages.items_per_page]
end

thats the part that it says is the problem, I just added the
:search_streams, :search_auds parameters to Event.search…I thought
that would fix the problem but now it’s telling me theres a wrong number
of arguments (3 for 1) instead of 2 for 3

It happens when I try to submit the form

ok, then the view code for the form is ok (should be, since none of the
used functions requires 3 arguments.

The error message should tell you, in which line the error happen.

Or just post the code of the keywords action.

maybe it could be happening in the switch from the ‘index’ view to the
‘keyword’ view?

keyword view:

<% form_tag(:controller => ‘search’, :action => ‘keyword’, :method =>
‘post’) do -%>
<%= check_box_tag(:search_streams) %>Search Streams

<%= check_box_tag(:search_auds) %>Search Audiences

<%= text_field_tag ‘text’ -%>
<%= submit_tag ‘Search’ -%>


<% end -%>

<% if @events.any? %>

Events containing '<%= params[:text] %>':

    <% for event in @user_events %> <% if !event.hidden? || (event.hidden? && event.admin_by?(current_user))%>
  • <%= render :partial => 'calendar/edit', :locals => {:event => event} %>
        <h3 class="summary"> <%= 
    

    textilize_without_paragraph(event.title) %>

        <%= render :partial => 'calendar/event_permalink', :locals => 
    

    {:event => event} %>

        <%= render :partial => 'calendar/event_top', :locals => {:event 
    

    => event} %>

        <%= render :partial => 'calendar/event_bottom', :locals => 
    

    {:event => event} %>

        <% if signedIn? %>
        <%= render :partial => 'calendar/event_options', :locals => 
    

    {:event => event} %>
    <% end %>

        <%= render :partial => 'calendar/event_all_occurrences', :locals 
    

    => {:event => event} %>

    </li>
    <% end %>
    

    <% end %>

<% unless @event_pages.length <= 1 %>

<%= pagination_links(@event_pages, :window_size => 4, :params => params) %>

<% end %>

<% else %>

No events found. Try another search.

I think it might be from not getting the values from the checkboxes on
the index view to the keyword view?

<% end %>

thats the part that it says is the problem, I just added the
:search_streams, :search_auds parameters to Event.search…I thought
that would fix the problem but now it’s telling me theres a wrong number
of arguments (3 for 1) instead of 2 for 3

the 3 for 1 error comes from that code

params[:search_streams, :search_auds, :text]

it’s a hash, you can’t use it that way.

do you still have:
def self.search(keywords, options = {}, *args)

or did you change it?

@events = Event.search params[:search_streams, :search_auds, :text], …
should
@events = Event.search [params[:search_streams], params[:search_auds],
params[:text]], …

then in search the argument keywords would be an array, containing those
three values (not the way I would do it…

def self.search(keywords, search_streams, search_auds, options = {},
*args)

and call with
@events = Event.search params[:text],params[:search_streams],
params[:search_auds], …

should work

Scratch that problem, I fixed it…silly me, I put

@events = Event.search params[:search_streams, :search_auds, :text], 

when I should’ve had:

@events = Event.search params[:search_streams], 

params[:search_auds], params[:text], …

oh, and I had changed the search to:

def self.search(search_streams, search_auds, keywords, options = {},
*args)

as you suggested before :slight_smile:

And it looks as if everything’s working properly now!

Thanks so much for you help, I really appreciate it!! Hopefully I can
handle this from here on out :slight_smile: