Database Structure for Multiple Form Checkboxes in Rails
I have a rails app I am working on that allows users to create a schedule. In doing so, they should be able to select on which days of the week an event occurs. The way I was planning on doing this in a form was a checkbox next to every, weekday, like so:
<%= f.check_box :monday %&开发者_JS百科gt; <%= f.label :monday %>
<%= f.check_box :tuesday %> <%= f.label :tuesday %>
<%= f.check_box :wednesday %> <%= f.label :wednesday %>
etc...
However, It occured to me that this probably isn't a very efficient way of handling this, storing each date as a boolean value in the database. It will be very difficult to display the dates in the 'show' view; I'll have to do something like
Event Dates:
<% if @event.monday? %>
Monday
<% end %>
<% if @event.tuesday? %>
Tuesday
<% end %>
<% if @event.wednesday? %>
Wednesday
<% end %>
Which seems less than ideal to me.
My other idea would be to just create one string column in the database that holds all of the event dates, using attr_accesors and a model method to create the string after_create. However, in this case, how will users be able to edit the Event?
It got me thinking, there must be some sort of best practice here that I don't know about (I've never tried to create something with this type of structure before).
Any advice?
Thanks!
Don't do this:
My other idea would be to just create one string column in the database that holds all of the event dates, using attr_accesors and a model method to create the string after_create.
That sort of thing will just cause problems like making per-day queries a horrific ugly mess; how would you, for example, count how many events are available on Monday if you stored your days mashed into a single column?
Instead, keep your seven booleans and add a simple convenience method to your model that returns the days in some more convenient format. Something like this perhaps:
def days
Date::DAYNAMES.map { |d| read_attribute(d.downcase) }
end
and then you can simply iterate over @event.days
in your view and map the day numbers to names:
<% @event.days.each_with_index do |on_day, i| %>
<% if on_day %>
<%= Date::DAYNAMES[i] %>
<% end %>
<% end %>
The specific details of the days
method and how you deal with it in your ERB will, of course, depend on your specific circumstances.
A detailed better code than the approved one "In my opinion" would be:
Model:
serialize :days
def weekdays
Date::DAYNAMES.map { |d| d.upcase }
end
View:
<% Model.weekdays.each do |day| %>
<%= check_box :model, :days, { :multiple => true }, day.downcase, nil %> <%=day.downcase %>
<% end %>
%{Mon Tue ... Sun}.each_with_index do |day, index|
<%= check_box_tag 'name', '1', model.attribute[index].to_i %>
end
Yes workaround but should work
to match records from DB that occur on Sunday
Model.where("models.name LIKE '1______'")
精彩评论