Wedding + 2

Sean was kind enough to give us congratulations from his blog. Thanks!

Today got off to a bang. Last night we devised a list of questions to ask our lawyer first thing in the morning… and this morning we got the answers

Q. Do we have to fill out the G-325A Biographical information, or do they?
A: The law office will, and they sent out draft forms yesterday .
Result: Updated drafts will be hand delivered backto the lawyer tomorrow.

Q. Where to get I-693.
A. Instructions were provided.
Result: Appointment set up for July 5.

Q. What is “Police Clearance? (If applicable)” requirement about?
A: It’s not applicable.
Result: The issue’s mute!

Then went to Walgreens to print up pictures of us for the “bona fide” relationship requirement. Got them back this afternoon, wrote a summary and date on the back of each, and now their in the envelope with the updated drafts. Forms and paperwork took long enough, but eventually that we set out for today was finished.

The Greencine Five, Part II: Phantom India, Tribulation 99, Immortal, Twin Peaks, Gattaca

Sometimes clicking “rent” at things that look vaguely interesting gets you classics, like I’m Not Afraid. At other times — well, you get my last two weeks of movie watching. That “Gattaca” is the highlight of the list says a lot. I would have had more fun watching any of the movies on the Awful Movie Database.


Paternalistic Marxism

Like Twin Peaks Season 2 Disk 2 (reviewed below), this second disk is one DVD too many. The director’s orientalism, marxism, and general Frenchism (calling the Jews degenerate was a nice touch) gets tiring, as does his superficially informative documentary about India. If you want to see what India’s true problems in the 1960s were, watching Commanding Heights. If you need to punish yourself to restore karma from a particularly bad dead — say, the sacking of Samarkand — then finishin Phantom India. If you liked Amin Maalouf’s In the Name of Identity, as I didn’t, you may be able to tolerate this movie.


Republicans = Molemen

A real conspiracy theory wrapped inside a false one, Tribulation 99 starts out fanatistically strange.. and ends as yet another angry, campus-radical screed against Reagan, Bush, the United Fruit Company, and counter-revolutionary generally. The whole film is about 50 minutes long — watch the first half, then throw the disk away. (Or, if you subscribe to greencine, return it and get another in the mail!). Many references will be familiar to Coast to Coast AM fans. If the film hadn’t strayed so far into late-eighties-campus-leftist paranoia it would have been a classic.


Thank you, France.

Immortal deserves 3/10 stars because portions of the soundtrack are courtesy of Sigur Ros. Without this touches it’s a solid 1/10. A dull French fantasy about revolution in a futuristic New York
features, among other things, a floating pyramid and an uncomfortable fixation with schizophrenic rape.


And the murderer is…

If Season 2, Disk 1 of Twin Peaks was the equivalent of how LOST’s second season started out, Season 2, Disk 2 is the equivalent of how LOST’s third season began: awful. The pacing is slow, all the interesting stuff is missing, and the acting is hardly believable. The only redeeming feature is that the first scene of the first episode on the disk ties into the last scene of the last episode. I only watched this disk because I want to watch every episode of the series, in its proper order, by the end of the summer. Not recommended.


Run! Science!

A stylish sci-fi drama set in a futuristic 1950s, Gattaca is based on a simple fact: as variation in environment decreases, the variation in outcomes explained by genetics decreases. This is not a terrible thing — unequal environments, of course, are how we can look at low IQ across Africa without resorting to racial explanations. Gattaca drags on, but makes one think a lot. Final verdict: Below-average but still good.

Creating a Basic Question Interface

Having created a basic question-list interface (functionally the same as MediaLab’s que file), today the admin interface is expanded to have a basic question interface.

The standard static scaffold is actually inappropriate for how we’ll want questions to be generated (something like the experiment controller’s ajax will be require), but for now let’s just get it working.


One major change is we will create a Class Constant (enumeration) for our question types, with apologies to RubyFleebie:

Create a module named question_type.rb

class QuestionType
def self.add_item(key,value)
@hash ||= {}
@hash[key]=value
end

def self.const_missing(key)
@hash[key]
end

def self.each
@hash.each {|key,value| yield(key,value)}
end

def self.find_selection_list
@hash
end

QuestionType.add_item :STRING, 1
QuestionType.add_item :TEXT, 2
QuestionType.add_item :SELECTION, 3
QuestionType.add_item :CHECKBOX, 4
QuestionType.add_item :RADIO, 5
end

Change question.rb:

class Question < ActiveRecord::Base
validates_presence_of :name, :display, :type, :list_id
validates_uniqueness_of :name
end

make sure question_list.rb is to

class QuestionList < ActiveRecord::Base
validates_presence_of :name, :description

def self.find_name_by_id(selected_id)
found_object = find(selected_id)
@to_return = found_object.name
end

def self.find_selection_list
@conditions = QuestionList.find(:all ).map {|u| [u.name, u.id] }
end

end

Uh oh. I realized I may have used another special name in a migration like I did on day one. No problem. Generate a new migration:

019_alter_questions should be:

class AlterQuestions < ActiveRecord::Migration
def self.up
add_column :questions, :type_id, :integer
remove_column :questions, :type
end

def self.down
remove_column :questions, :type_id
add_column :questions, :type_id, :integer
end
end

Then rake db:migrate

app/views/manage_questions/_form.rhtml:

<%= error_messages_for ‘question’ %>

<!–[form:question]–>
<p><label for="question_name">Name</label><br/>
<%= text_field :question, :name %></p>

<p><label for="question_display">Display</label><br/>
<%= text_area :question, :display, :rows => 3 %></p>

<p><label for="question_type_id">Type</label><br/>
<% @question_types = QuestionType.find_selection_list %>
<%= select :question, :type_id, @question_types %>

<p><label for="question_list_id">Question List</label><br/>
<% @question_lists = QuestionList.find_selection_list %>
<%= select :question, :list_id, @question_lists %>
<!–[eoform:question]–>

Apparently, display is a special word too, so create yet another migration…

ruby script/generate migration alter_questions_replace_display_with_display_text

And make 020_alter_questions_replace_display_with_display-text.rb like so:

class AlterQuestionsReplaceDisplayWithDisplayText < ActiveRecord::Migration
def self.up
remove_column :questions, :display
add_column :questions, :display_text, :text
end

def self.down
remove_column :questions, :display_text
add_column :questions, :display, :text
end
end

Then rake db:migrate

Now to to question.rb, _form.rhtml, list.rhtml changing names as appropriate

Now, only one more thing to do: create default options where appropriate.

_form should now look like:

<%= error_messages_for ‘question’ %>

<!–[form:question]–>
<p><label for="question_name">Name</label><br/>
<%= text_field :question, :name %></p>

<p><label for="question_display">Display</label><br/>
<%= text_area :question, :display_text, :rows => 3 %></p>

<p><label for="question_type_id">Type</label><br/>
<% @question_types = QuestionType.find_selection_list %>
<%= select :question, :type_id, @question_types %>

<p><label for="question_list_id">Question List</label><br/>
<% @question_lists = QuestionList.find_selection_list %>
<%= select :question, :list_id, @question_lists %>

<p><label for="question_options">Default Options</label><br />
<% 1.upto(10) do |iterator| %>
<%= text_field :question_options, iterator %>
<% end %></p>

<!–[eoform:question]–>

Now we need to add default option awareness to the controller. Again, >yeseterday’s work will be a guide.

But first, another change (aren’t you glad we have migrations?)

ruby generate/migration alter_question_options

021_alter_question_options.rb:

class AlterQuestionOptions < ActiveRecord::Migration
def self.up
remove_column :question_options, :name
remove_column :question_options, :optiontext
add_column :question_options, :option_id, :integer
add_column :question_options, :display_text, :text
end

def self.down
remove_column :question_options, :option_id
remove_column :question_options, :display_text
add_column :question_options, :name, :string
add_column :question_options, :optiontext, :text
end
end

Then rake db:migrate

Now, update two functions in manage_questions_controller.rb

def create
#render_text params[:question][:display]
@question = Question.new(params[:question])
@result_of_save = @question.save

if @result_of_save

@question_options = params[:question_options]
for question_option in @question_options
@question_option_id = question_option[0].to_i
@question_option_text = question_option[1].to_s
if @question_option_text
QuestionOption.add_by_question_id_option_id(@question.id,@question_option_id,@question_option_text)
else
QuestionOption.destroy_by_question_id_option_id(@question.id,@question_option_id)
end
end
flash[:notice] = ‘Question was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

def edit
@question = Question.find(params[:id])
end

def update
@question = Question.find(params[:id])
if @question.update_attributes(params[:question])

@question_options = params[:question_options]
for question_option in @question_options
@question_option_id = question_option[0].to_i
@question_option_text = question_option[1].to_s
if @question_option_text
QuestionOption.add_by_question_id_option_id(@question.id,@question_option_id,@question_option_text)
else
QuestionOption.destroy_by_question_id_option_id(@question.id,@question_option_id)
end
end

flash[:notice] = ‘Question was successfully updated.’
redirect_to :action => ‘show’, :id => @question
else
render :action => ‘edit’
end
end

Change the question_option.rb module:

class QuestionOption < ActiveRecord::Base
validates_presence_of :question_id, :option_id, :display_text

def self.add_by_question_id_option_id(question_id,option_id,display_text)
self.destroy_by_question_id_option_id(question_id,option_id)

to_add = self.new(
:question_id => question_id,
:option_id => option_id,
:display_text => display_text
)
to_add.save
return to_add
end

def self.destroy_by_question_id_option_id(question_id,option_id)
to_destroy = find_by_question_id_option_id(question_id,option_id)

to_destroy.destroy if to_destroy
end

def self.find_by_question_id_option_id(question_id,option_id)

to_return = find(
:first,
:conditions => {
:question_id => question_id,
:option_id => option_id
}
)

to_return
end

end

The very last things that we need to do is to work on the manage_question_list_conditions_controller (which as I’ve added and deleted data spontaneously stopped working) and the question_options controller (so we can see the options we just added — sometime later we will integrate this functionality with the main controller)

The specific problem with the QuestionListConditionsController reads:

Showing app/views/manage_question_list_conditions/list.rhtml where line #13 raised:

Couldn’t find QuestionList with ID=6

With the extracted source:

<tr>
<td><%= question_list_condition.id %></td>
<td><%= Condition.find_name_by_id(question_list_condition.condition_id) %></td>
<td><%= QuestionList.find_name_by_id(question_list_condition.question_list_id) %></td>
</tr>
<% end %>
</table>

So what we need to do is to alter QuestionList’s module’s find_name_by_id to encorporate some basic exception handling (actually we should have exception handling all over the place)

So change QuestionList:find_name_by_id to

def self.find_name_by_id(selected_id)
begin
found_object = find(selected_id)
@to_return = found_object.name
rescue
@to_return = “Error: No Name found for id ” + selected_id.to_s + ” generated by question_list.rb:find_name_by_id”
end
@to_return
end

(not exactly pretty, but right now focus on the structure).

Update question.rb:

class Question < ActiveRecord::Base
validates_presence_of :name, :display_text, :type_id, :list_id
validates_uniqueness_of :name

def self.find_name_by_id
to_find = find(selected_argument_id)
@to_return = to_find.name
end
end

And finally app/views/manage_question_options/list.rhtml

<h1>Listing question_options</h1>

<table>
<tr>
<th>ID</th>
<th>Question ID</th>
<th>Question Text</th>
<th>Option</th>
<th>Display Text</th>
</tr>
<% for question_option in @question_options %>
<tr>
<td><%= question_option.id %></td>
<td><%= question_option.question_id %></td>
<td><%= Question.find_name_by_id(question_option.question_id) %></td>
<td><%= question_option.option_id %></td>
<td><%= question_option.display_text %></td>
<td><%= link_to ‘Show’, :action => ‘show’, :id => question_option %></td>
<td><%= link_to ‘Edit’, :action => ‘edit’, :id => question_option %></td>
<td><%= link_to ‘Destroy’, { :action => ‘destroy’, :id => question_option }, :confirm => ‘Are you sure?’, :method => :post %></td>
</tr>
<% end %>
</table>

<%= link_to ‘Previous page’, { :page => @question_option_pages.current.previous } if @question_option_pages.current.previous %>
<%= link_to ‘Next page’, { :page => @question_option_pages.current.next } if @question_option_pages.current.next %>

<br />

<%= link_to ‘New question_option’, :action => ‘new’ %>

Another days work done!

Tomorrow: showing the defaults on the questions and question-lists controller.