Category Archives: Ruby on Rails

Saying goodbye to Rails

I give up.

Everywhere I look suggests that what I have should be enough for this to work. But it isn’t.

And since this is a fundamental feature of the project, and what with the still patchy cross-browser performance of JQuery auto-select, it’s time to abandon Rails and look for another framework.

So, I will be taking a pause while I get Django up and running. Rails is no more.

Wot, no controller?

While considering where I was going wrong with my Rails project, I figured that since I had the model and the views covered, I ought to give some consideration to the controller.

Then it occurred to me that the reason why no form elements were being shown on the new commission page was because I hadn’t created any! The standard scaffold controller action can be a little basic with show and edit completely blank.

But the ‘new’ controller does create an object and this is where the form elements com from. And in earlier tests, I had seen that I could use a build method to create the nested attributes. This should be easy.

Surely all my controller needs is:

 def new
   @commission = Commission.new
   @commission.build_activity
 end

So why does that give me the following error:

undefined method `build_activity' for #<Commission:0x007f9e10be7020> Did you mean? build_commission_type

I can change the controller as suggested,

 def new
   @commission = Commission.new
   @commission.build_commission_type
 end

And although the page loads, there are no form elements displayed. It’s wrong anyway, so I’m not bothered about that.

Perhaps the problem boils down to using a word that that plurals with ‘ies’ and that needs to be reflected in the appropriate places: sometimes singular sometimes, plural, other times pluralised. Sometimes errors, sometimes nothing.

This is the Rails way: everything’s a battle. Every step of the way.

3 sources, all slightly different, none work

Now on the case with http://apidock.com/rails/v4.2.1/ActionView/Helpers/FormHelper/fields_for (yes, I know, Rails 4, probably isn’t supported in 5) and mentions more possibilities that probably aren’t relevant, but don’t work anyway.

I mention it here because if (I’m not confident enough to say when) I get this working I will be needing to auto-populate some fields (am I mad!) and there might be value in the comments.

It’s another one of those times when it’s clear that I’m doing something wrong (other than actually attempting to do this) but I have no idea what and very little indication of where to start looking. For all the times that development can accelerate with Rails, there are these occasions when it grinds to a halt and you’re never actually sure how it got fixed.

It couldn’t last

It didn’t take long for my development with polymorphic associations and forms to founder.

The very next stage after my last post on the matter, in fact. And I now have a second reference source that, while providing an additional nudge, isn’t enough to see me through the current block.

To be able to nest the activity section on the commission form, we need to tell the commission model to accept activity fields,

accepts_nested_attributes_for :activities

(I originally hd this as :activity after the model name, but it gave a missing model error; then my initial hunch was probably that accepts_nested_attributes_for was no longer supported in Rails 5; these things rarely work for very long).

A quick search on the topic of continued rails support for accepts_nested_attributes_for took me to https://rubyplus.com/articles/3681-Complex-Forms-in-Rails-5, which is a nicely written page which only backs up my original source. Curiously, however, it includes a step that shows successful data posts before they’ve been added to the form.

Then we simply add the following to the commission form,

 <% f.fields_for :activities do |act| %>
 Title: <%= act.text_field :title %>
 Details: %= act.textarea :details %>
Number of slots: <%= act.number_field :number_of_slots %>
 Min slot separation: <%= act.number_field :min_slot_separation %>
 <% end %>

Then nothing. No errors, log messages or anything. Nothing. Nothing ever works the way it’s described and a heavy price is to be paid for every advance.

 

Rails polymorphic associations

The first in a likely series of posts regarding polymorphic associations in Rails that will illustrate my hitherto lack of understanding about how they work and my (hopeful) development to being able to use them effectively in my current project.

I’m going to need reminders and reference points when I get deeper into the project and start to make progress. I don’t necessarily expect this to be of use use to anyone else.

First off, I’m using https://6ftdan.com/allyourdev/2015/02/10/rails-polymorphic-models/ as a reference; so far it’s working well for me.

Start with a new git branch in case things don’t work out.

$ git checkout -b polymorphic_activities

The activities table already includes activityable_type and activityable_id columns but I needed another migration to the table to do the half-baked ideas I had before/

The Commission model includes,

class Commission < ApplicationRecord
belongs_to :request
 belongs_to :commission_type
 has_many :activities, :as => :activityable, :dependent => :destroy

The Activity model includes

class Activity < ApplicationRecord
 validates :title, :presence => true, :uniqueness => true
 validates :activityable_id, :presence => true
 validates :activityable_type, :presence => true
 
 belongs_to :activityable, :polymorphic => true

And we can test this with the Rails console with something like,

2.3.3 :002 > commission = Commission.first
2.3.3 :005 > commission.activities.build(title: "Background layers", details: "do some prep layers", number_of_slots: 3, min_slot_separation: 3).save

And we get an entry in the activities table with activityable_type set to Commission and activityable_id set to the id of the commission. Looks promising.

The main point at this stage is that I can bin the activity_commission, activity_other, activity_teaching tables (with ActivityCommission as the activityable_type) and just use Commission, etc. I’m beginning to see how this might work for all the other activity-based relationships I need to model. No need to abandon the project just yet.

Automating builds and testing with Jenkins

Now, I’m more than well aware that I’m on a well-trodden path here, but this is more as a reminder of some basic setup for future use.

With previous Rails projects I have undertaken, I have tried to incorporate the testing after a significant amount of the code has been written, making a serious test scenario unfeasible.

With my latest project, however, I’m taking the time to include testing from the get-go. So, with the first few models created I have taken the time – about 50% of the project time thus far – to get a set of successful model and controller tests; there may be a separate posting to cover this.

With testing in place and with GitHub being used as the SCM, I’m in a position to automate the build and test process. I’m thinking of deploying the application to a personal AWS account and building a pipeline to build and deploy after commits.

Anyway, using my Arch Linux desktop machine as the testing server, I installed Jenkins and started the service. I started working from the getting started guide at https://jenkins.io/ but didn’t fancy getting to grips with Groovy and the pipeline.

I found a simple guide for configuring Jenkins to build and deploy a Rails project and decided to see if I could a tangible result.

The Jenkins installation creates a user account with a home directory, /var/lib/jenkins, and to work with a Freestyle project we need a .bashrc to set up the environment for the build script.

COMMISSIONS_USER="mysql-user"
COMMISSIONS_PSWD="mysql-pssword"
COMMISSIONS_HOST="localhost"
COMMISSIONS_DB="test_database"
TEST_SECRET_KEY_BASE="... random.charcters.for.secret.key..."
MYSQL_SOCK="/path/to/mysqld.sock"
export COMMISSIONS_USER COMMISSIONS_PSWD COMMISSIONS_HOST COMMISSIONS_DB TEST_SECRET_KEY_BASE MYSQL_SOCK
echo "Exported Rails and MySQL environment for $LOGNAME"

These are to match the environment references in the database and secrets YAML files from the repository; the last line is helpful for checking the console output.

The build script then becomes the following,

#!/bin/bash

export RAILS_ENV=test
. $HOME/.bashrc

cd . # Force RVM to load the correct Ruby version

/usr/bin/bundle install
/usr/bin/bundle exec rails db:create db:schema:load db:migrate
/usr/bin/bundle exec rails test

Now, because I typically use rvm for the ruby install for my account, the gems required fo the application aren’t generally available. This means that the bundle command will require privilege escalation to install the gems and we need to permission the jenkins account needs an entry or two in /etc/sudoers (which can be removed after the first bundle has completed, but will be required for each new gem).

jenkins ALL=NOPASSWD:/usr/bin/bundle
jenkins ALL=NOPASSWD:/usr/bin/gem
jenkins ALL=NOPASSWD:/usr/bin/rake

And with all that in place we can ask Jenkins to build now and get a clean run and with  daily schedule for builds we can start on the development cycle making sure we continue to test as we go.

References

http://nithinbekal.com/posts/jenkins-rails/ – a basic guide (for Ubuntu) adapted for my setup

Rails 5 jQuery datepicker

I’m embarking on another Rails project and of course there’s been a version bump that I’m going to have to get used to; hopefully I can still remember some of the old stuff.

One of the requirements for the front page is a date selector and since I’ve used a bit of jQuery before…

But this is Rails and life is never that simple.

It starts easily enough and a quick search leads to http://www.rubydoc.info/gems/jquery-ui-rails/5.0.5 which suggests adding a gem, a line in application.js and application.css and Bob’s your uncle.

What the page fails to mention is that taken at face value it doesn’t work. And it doesn’t give an example of how it might be used in a Rails template. There is a note on the page about steps required for certain versions, but it’s not clear that this is actually for current works not old versions.

It turns out that just including ‘gem jquery-ui-rails’ will install version 6 and this isn’t good. What we really need is

gem 'jquery-ui-rails', '5.0.5'

And then, application.js gets the following,

//= require jquery-ui/datepicker

And application.css is treated with,

*= require jquery-ui/datepicker

And with slight trepidation, some CoffeeScript (I fail to see the point of a language to write languages; this isn’t assembler),

jQuery ->
 $('#datepicker').datepicker();

And swapping the date_select helper in the form template with,

<%= f.text_field :due_date, :id => "datepicker" %>

And it works! It’s the “, ‘5.0.5’ that makes the difference.

References

http://stackoverflow.com/questions/15727660/rails-jquery-ui-datepicker – for help with the general approach.

http://stackoverflow.com/questions/42495010/couldnt-find-file-jquery-ui-datepicker-with-type-application-javascript – this page is in response to the displayed by following the default instructions and references the easily-missed version warning.