spring15wad / rollingread

RollingRead - Project 2 & 3 for Web Application Development COM531 at Illinois Tech
0 stars 1 forks source link

Make days as arrays #8

Closed mfreema5 closed 9 years ago

mfreema5 commented 9 years ago

In migration use :array = > true to make an array column. (So, it's still a date…?)

course.meet_days and course.all_days should be arrays.

course.meet_days is an array of the days of the week on which the class meets.

course.all_days is an array containing every day that the course meets during the semester.

Use semester.start_date, semester.end_date, and course.meet_days to generate course.all_days. Put a method in the model. That method gets called by controller for create or update.

# ¡PSUEDO CODE!

def complete_days
  loop_day = semester.(params[:semester]).start_day
  course.meet_days[].each do | weekday | 
    if loop_day.wd != weekday
    do
      loop_day = loop_day + `1 day`
    done
    i = 0
    while loop_day < semester.(params[:semester]).end_day
    do
      course.all_days[{#i}] = loop_day
      loop_day = loop_day + '7 days'
      i = i + 1
    done
end

Elements in course.all_days aren't in chronological order. Sort them in the method? Or just sort them when we use them?


To use hashes in DB (probably won't, but in case we do…)

Notes from H is for Hstore.

In Gemfile: gem "pg"

In config/database.yml:

development:
  adapter: postgresql
  database: appname_development
  pool: 5
  timeout: 5000
  host: localhost

test:
  adapter: postgresql
  database: appname_test
  pool: 5
  timeout: 5000
  host: localhost

in application.rb: config.active_record.schema_format = :sql

Iin the migration file:

class AddHstore < ActiveRecord::Migration
  def up
    execute 'CREATE EXTENSION hstore'
  end

  def down
    execute 'DROP EXTENSION hstore'
  end
end

In add_column migration, specify hstore as the column type:

class AddHstoreColumnToUsers < ActiveRecord::Migration
  def change
    add_column :courses, :weekdays, :hstore
  end
end

To access the keys in the hash, set them through a method called store_accessor in the model:

class Course < ActiveRecord::Base
  store_accessor :weekdays, :sunday, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday
end
mfreema5 commented 9 years ago

So, I have a method, every_meet_day(meet_days,start_date,end_date). (Ruby test code is in metawad: all_days-testing.rb.)

I've put that method into the model, course.rb. The method should be used in the create and update methods of courses_controller.rb. The POST params will have the meet_days array (presumably), and a semester_id that can be used to get start_date and end_date.

The method will return an array, which should go into course.all_days (currently doesn't exist).

How in the hell do you do that?

The example from the Rails Guide reads to me like gibberish:

  # This action uses POST parameters. They are most likely coming
  # from an HTML form which the user has submitted. The URL for
  # this RESTful request will be "/clients", and the data will be
  # sent as part of the request body.
  def create
    @client = Client.new(params[:client])
    if @client.save
      redirect_to @client
    else
      render "new"
    end
  end

So, as far as I can tell, that example method will pass client to client unless of course client, in which case, client. Highly elucidating, that. </sarcasm>

thedanmartin commented 9 years ago

I read that as client will pass a revised/edited/updated/etc version of client to replace the original client if a revised/edited/updated/etc version of client is saved, at which point the user will be redirected to the new client. Otherwise, it renders new?

I'm terrible at this shit, though.

mfreema5 commented 9 years ago

I ain't much better, trust me. But I ate some lunch (blood sugar FTW!), and I think it's:

Create an instance of class Client referred to as @client, using params[:client]. Then try to save the instance; in other words, use the method save on @client. If that method returns true… I don't know after that. Is redirect_to a path, or a helper? And WTF does render "new" do?

mfreema5 commented 9 years ago

More Rails documentation rage: Form Helpers.

Basic Structures

The two basic structures are arrays and hashes.

And then every single goddam example is a hash. I want an array. Let me guess “Arrays are obvious, so we explain hashes.” Dipwads.

This guide is designed for beginners

Yeah, that's why you gloss over the “obvious” stuff, you lazy bastards. Because there ain't nothing more user friendly than assuming people understand the basic case and therefore only covering the advanced cases.

mfreema5 commented 9 years ago

I've simply added 7 check_box_tags to courses/_form.html.haml. It successfully passes an array back to courses_controller.rb, which then promptly ignores the array and pukes out a nil:Classnil error. I have no idea why.

And I also have no idea how, when updating, to pre-check the right boxes. Maybe some kind of loop? A fields_for helper? Can I hire Denisse?

mfreema5 commented 9 years ago

So, here's what worked.

On the form, have checkboxes that feed into an array. (Rails implicitly knows to make an array when the name is of the form model[attribute][].)

  .field
    = f.label :meet_days
    <input type='checkbox' id='meet_days[Monday]'    name='course[meet_days][]' value=1>M</input>
    <input type='checkbox' id='meet_days[Tuesday]'   name='course[meet_days][]' value=2>T</input>
    <input type='checkbox' id='meet_days[Wednesday]' name='course[meet_days][]' value=3>W</input>
    <input type='checkbox' id='meet_days[Thursday]'  name='course[meet_days][]' value=4>H</input>
    <input type='checkbox' id='meet_days[Friday]'    name='course[meet_days][]' value=5>F</input>
    <input type='checkbox' id='meet_days[Saturday]'  name='course[meet_days][]' value=6>S</input>
    <input type='checkbox' id='meet_days[Sunday]'    name='course[meet_days][]' value=0>U</input>

Back at the controller, for a new record, this loopy construct works:

  def create
    @semester = Semester.find(course_params[:semester_id])
    @course = Course.new(course_params[:course]) do |c|
      c.course_number = course_params[:course_number]
      c.short_course = course_params[:short_course]
      c.full_course = course_params[:full_course]
      c.meet_days = course_params[:meet_days]
      c.all_days = every_meet_day(c.meet_days,@semester.start_date,@semester.end_date)
      c.semester_id = course_params[:semester_id]
    end

For an update, you can take just the array from the form and pass it to the method:

    @course.all_days = every_meet_day(course_params[:meet_days],@semester.start_date,@semester.end_date)

Specifically, this method (where, as with the array on the form, we make an array by using empty brackets, all_days = []).

    def every_meet_day(meet_days,start_date,end_date)

      all_days = []
      i = 0

      meet_days.each do | this_day |

        loop_date = start_date

        while loop_date.wday < this_day.to_i
          loop_date = Date.jd(loop_date.jd + 1)
        end

        while loop_date < end_date
          all_days[i] = loop_date
          loop_date = Date.jd(loop_date.jd + 7)
          i = i + 1
        end
      end
      return all_days.sort
    end