I may have over-complicated what I need to do but this is what I now have.
I have a jobs controller that has 2 fields
starts_at as DATETIME
end_time as DATETIME
I save the event_date in a form using a
calendar_date_select :starts_at ,:time => false
I save the date time as
time_select :starts_at, {:twelve_hour => true}
This saves the Event date i.e 12/26/2009 and the start time as 7:00 pm
I need to also save the event end_time without having to re-enter the date, just the time
time_select :end_time, {:twelve_hour => true}
If i just use the above, the time is correct but the date dafaults to 01/01/2000
How do I save the date with the same date from starts_at?
In your controller, if the :end_time is nil, set it to the :starts_at variable like so:
object.end_time = object.starts_at unless not object.end_time.nil?
You may be able to shorten the end to
object.end_time = object.starts_at unless object.end_time.present?
but I'm not sure which version of Rails you are using and what the default implementation of .present? does for dates.
You could do this in the model or controller, but isn't it possible that an event will start late at night and end on the following day? To allow for this possibility I'd recommend having two calendar_date_selects and auto-assigning the ending date when the starting date is chosen (so the second calendar_date_select will rarely be used).
If you really don't want two calendars, maybe use a hidden field for the ending date that follows the start date.
I wouldn't enforce this same-date rule below the interface level unless you're absolutely sure different start and end dates will never occur.
Related
As part of an application I'm building, I need to store the days on which some action needs to happen.
Currently I have this stored in a 7-digit bit-string, with each digit corresponding to one day of the week. A value of 1 for any day means the action should happen that day, a value of 0 means it should not.
Ex. String 0101110 means the action should run on Tuesday, Thursday, Friday and Saturday every week.
In my form, I have seven checkboxes set up, one for each name.
How would I go about merging these seven Boolean results into the one bitstring, such that I can save it in the database?
Would you do this in the view, or the model?
I've done some thinking myself, and one option (in the view) could be to set up a hidden field in the form that is the result of joining/concatenating the seven Booleans from the checkboxes. Then the checkboxes' values could be discarded on submit. I'm just not quite sure how to do this in rails.
Another option could be to handle the merging in the model. Again - not quite sure what to do.
Any help appreciated, thanks in advance.
Define the checkbox values for the weekdays as virtual attributes on your model, and concatenate them on a before_save hook. In your model:
attr_writer :mon, :tue, :wed, :thu, :fri, :sat, :sun
before_save :set_weekdays
private
def set_weekdays
self.weekdays = bitstr(#mon) + bitstr(#tue) + bitstr(#wed) # etc
end
def bitstr(bool)
bool ? "1" : "0"
end
Make sure to permit mon and co as strong parameters for the model in Rails 4. You might also want to define getters for these attributes that would get filled from the bitstring, so that the form could render with the correct checkboxes pre-selected on edits.
I am assuming the week column is week
You can make the week column of type: text and add this to your model
serialize :week : this helps to save an array in the column
next, create a class Week, where week.rb:
class Week
include ActiveModel::Model
attr_accessor :id, :name
DAYS = [
{id: 1, "day" => "monday"},
{id: 2, "day" => "tuesday"},
...
]
def self.days
DAYS.map {|d| self.new(
id: d[:id],
name: d[:day]
)}
end
end
and then, you can call the checkboxes from the view as follow:
<%= f.collection_check_boxes(:week, Week.days, :id, :name, include_hidden: false) do |b| %>
<%= b.check_box(class: "check_box") %> <%= b.object.name %>
<% end %>
lastly, dont forget to make the week atribute accesible from the controller. In rails 4, this will be:
params.require(:user).permit(week: [])
Hope this helps you?
Hi i'm a beginner in RoR and was having a little bit trouble in generating a particular model.
I want to create 2 models - List and Item. The List has_many Items and Item belongs_to List.
I want the Item model to have 3 attributes. rails g model Item name:string desc:string date:????
1.What data type to add for date:???
2.What format will the date attribute be in? (mm/dd/yy)?
3.And what kind of form input should it have?
f.date_field :date?
Thanks in advance!
1. What data type to add for date:???
In your migrations, you can use the following types for columns:
:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean
(extracted from the add_column transformation here)
In your case, if you don't need to store the time, you can use date:name_of_your_field.
2. What format will the date attribute be in? (mm/dd/yy)?
The attribute will be stored as a ActiveSupport::TimeWithZone, and you will have to format it when displaying it. You can use Time#strftime to do so.
your_attribute.strftime("%m/%d/%Y") #=> "11/19/2007"
3. And what kind of form input should it have?
Yes, you can perfectly use:
f.date_field :date?
It will return a text_field of type “date”. Depending on the browser support, a date picker will show up in the input field.
I hope that helps! Happy coding!
You can either have date or datetime according to the documentation. Therefore:
rails g model Item name:string desc:string date:datetime
or
rails g model Item name:string desc:string date:date
But the best practice is to use DateTime as a general purpose representation of time.
Although I would probably call it something more descriptive than date. (And just fyi created_at and updated_at columns are already created for you.)
The type is pretty much format agnostic. You can format it with strftime:
%Y%m%d => 20071119 Calendar date (basic)
%F => 2007-11-19 Calendar date (extended)
%Y-%m => 2007-11 Calendar date, reduced accuracy, specific month
%Y => 2007 Calendar date, reduced accuracy, specific year
%C => 20 Calendar date, reduced accuracy, specific century
%Y%j => 2007323 Ordinal date (basic)
%Y-%j => 2007-323 Ordinal date (extended)
%GW%V%u => 2007W471 Week date (basic)
%G-W%V-%u => 2007-W47-1 Week date (extended)
%GW%V => 2007W47 Week date, reduced accuracy, specific week (basic)
%G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended)
%H%M%S => 083748 Local time (basic)
%T => 08:37:48 Local time (extended)
%H%M => 0837 Local time, reduced accuracy, specific minute (basic)
%H:%M => 08:37 Local time, reduced accuracy, specific minute (extended)
%H => 08 Local time, reduced accuracy, specific hour
%H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic)
%T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended)
%H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic)
%T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended)
%H%M%S%z => 083748-0600 Local time and the difference from UTC (basic)
%T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended)
%Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic)
%FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended)
%Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic)
%Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended)
%GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic)
%G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended)
%Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic)
%FT%R => 2007-11-19T08:37 Calendar date and local time (extended)
%Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic)
%Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended)
%GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic)
%G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended)
Thanks to #BWStearns for that quote
Finally as far as input field goes: Have a look at these Form helpers.
<%= date_field(:user, :born_on) %>
<%= datetime_field(:user, :meeting_time) %>
<%= datetime_local_field(:user, :graduation_day) %>
Here's my problem, I'll try to be concise.
I have a model Course that has_many Planning.
A Planning has a start_date and an end_date.
I want to retrieve (with sunspot) all the Courses that have a particular planning between a given start_date and an end_date.
The problem is that if I store in the model Course :
searchable do
date :start_date, multiple: true do
plannings.map(&:start_date)
end
date :end_date, multiple: true do
plannings.map(&:end_date)
end
...
end
I loose the fact that start_date and end_date are couples.
Is there a way / trick to store ranges?
Have almost the same problem, in my case start_date and end_date wasn't really a date, just a year (integer), solve it with multiple value fields as range:
searchable do
date :course_date, multiple: true do
plannings.map{|p| (p.start_date..p.end_date).to_a}
end
...
end
so course_date contain all years when courses going. If you have 2001-2003 and 2005-2007(2001, 2002, 2003, 2005, 2006, 2007) and search with equal_to.
A possibility would be to make your query in two times. First find the plannings, then find the courses restricting courses by ID.
Maybe not a very optimised one, but why try to optimize to soon...
Or to index hours with a function:
def happens_between_8_and_9
return true if start_date > 8..
end
searchable do
boolean :happens_between_8_and_9
boolean :happens_between_9_and_10
end
```
I'm working on creating a Rails app that allows users to set availability Sunday through Saturday, with a start time, end time, and location (simple string). I have an User object and I'm unsure of how to continue. I know I could have a large set of Time objects like so:
class User
field :mondayStartTime, :type => Time
field :mondayEndTime, :type => Time
field :mondayLocation, :type => String
field :tuesdayStartTime, :type => Time
field :tuesdayEndTime, :type => Time
field :tuesdayLocation, :type => String
...
field :sundayEndTime, :type => Time
field :sundayLocation, :type => String
end
However, this seems terribly inefficient, though creating another unique object class seems just as bad and only results in more lines of code. Is there an easier way of implementing start/end times for a Sunday through Saturday schedule?
Thanks!
At first glance, I'd create an "Availability" model/class (or something less prone to misspelling like "Schedule") with the attributes of start_at, end_at, location, and day_of_week - and have that class belong to the User (and with the User having a "has_many :availabilities" or "has_many :schedules"). That seems (again at first glance) to be the most efficient and easiest to get the data back out - and you can use that separate class to do things like grouping schedules/availabilities together more easily.
Have you thought about creating objects for each day of the week, that have a start, end and location property?
Or perhaps, a Jobs object(model) that has fields for start time, end time, and location.
This way it would be possible to do, has_many :jobs and then you can either narrow down, by day, or select by a particular day. The narrowing down should be feasible with the ruby Time Class or ActiveSupport class (3.days.from_now, etc).
irb(main):001:0> require 'active_support/all'
=> true
irb(main):002:0> 2.days.ago
=> 2012-04-03 08:30:31 -0700
irb(main):003:0> 2.days.from_now
=> 2012-04-07 08:33:01 -0700
EDITED TO SHOW ACTIVE SUPPORT TIME CLASS
I am trying to figure out the best way to display all records by date. I have a date_due column in my database that is a datetime field.
So my output would include every date for which there is an entry, like this:
April 1, 2011
- Buy tickets
- Pickup groceries
April 2, 2011
- Call client
I am trying to use the following method, which is not working: find_all_by_date_due
What's the easiest way to do this in Rails?
Railscasts has a nice cast on group_by :
http://railscasts.com/episodes/29-group-by-month
You could make the dates into an association and assign it an arbitrary ID through rails.
class Entry
belongs_to :date
end
class Date
has_many :entries
end
#entry.date.build(:date => 2011-02-01 20:23:22)
#entry.find_by_date(2)
Date.find(2).date
=> 2011-02-01 20:23:22