Changing Rails Boolean with a Button

I suddenly realized how to change a boolean with a button in a much easier way that the post I did yesterday. All I did was make a form with one hidden field (the boolean that I want to change) and just show the submit button.

Here is all that I put in my view:

  <% if case.hidden? %>
    <%= form_for case do |f| %>
      <%= f.hidden_field :hide, value: false %>
      <%= f.submit 'Unhide' %>
    <% end %>
  <% else %>
    <%= form_for case do |f| %>
      <%= f.hidden_field :hide, value: true %>
      <%= f.submit 'Hide' %>
    <% end %>
  <% end %>

I didn't need to make any extra routes or methods. Very simple and exactly what I was looking for.

Change a Boolean in Rails with a Button

There's a much easier way to do this, which I show in this post.

I have a rails model called cases. I've added a boolean value (called hide) to cases for not displaying the case in a view. What I wanted to be able to do, was have a button right next to the name of the case. If the value of case.hide is true (meaning the case is hidden), I wanted to show a button that would show "Unhide case" and cause the value to change to false if pressed. And if the value was false, the button would show "Hide case" and change the value to true when pressed.

I'm documenting how I did this for myself. It works, but I'm fairly certain that there's a better way to do this. I just don't know what it is.

Here's the part of the view with the buttons:

  <% if case.hidden? %>
    <%= button_to "Unhide", unhide_case_case_path(id: %>
  <% else %>
    <%= button_to "Hide", hide_case_case_path(id: %>
  <% end %>

My routes file:

 resources :cases do
    post 'hide_case', on: :member
    post 'unhide_case', on: :member

Cases controller:

def hide_case
	@case = Case.find(params[:id])
	@case.update(hide: true)
	redirect_to cases_path

def unhide_case
	@case = Case.find(params[:id])
	@case.update(hide: false)
	redirect_to cases_path

Here's how my routes look:

$ rake routes|grep hide
                    hide_case_case POST   /cases/:id/hide_case(.:format)                cases#hide_case
                  unhide_case_case POST   /cases/:id/unhide_case(.:format)              cases#unhide_case

This works. However, I feel that there should have been a way for me to do this using the regular update method in the controller. The hide_case and unhide_case methods are basically just rewriting that method. I tried a few different ways of using the update method, but none of them worked. So until I come up with a better idea, I'll use this.

The one other thing to remember is that button_to is an automatic POST method. (If I wanted to switch this to a link, I'd have to make some other changes because link_to is an automatic GET method.) That's why the routes file uses POST. The standard update uses PATCH. I'm not familiar enough with the differences between POST and PATCH to figure out if that was one of the problems I had with using the update method.

Rails Rewrite

I have a website that I've been using to track timesheets for a number of people. It's one of the first websites I wrote in rails, written about four years ago. The only person who really uses it is me, but a few other people also login to view the information. Anyway, the site was written in rails 3.2.11 and now the latest version is 4.2. I've decided that since I know a bit more rails now (I wouldn't say I'm a good programmer), I'd rewrite the program. It's not that elaborate, but it does work really well for me.

Anyway, after getting the database set up on my laptop, I thought that I'd copy the current data from the server to my laptop. This was pretty easy to do with mysqldump.

$ /usr/bin/mysqldump --opt rails_db -u user1 -p > rails_db.sql

I then brought the sql file to my laptop and loaded it into the database.

$ mysql -u user1 -p rails_db < rails_db.sql

This worked great. However, I then had the idea to add another field to one of my tables. I made a migration, but when I tried to run it things didn't work. I basically got a message that there were other migrations that needed to run. A quick look at the database shows the problem.

Before loading the old sql file, the schema_migrations table looked like this:

| version        |
| 20150205145024 |
| 20150210163003 |
| 20150210200817 |
| 20150210210129 |
| 20150211152635 |

After loading the old database, the schema_migrations table looked like this.

| version        |
| 20111201141509 |
| 20111202204541 |
| 20111203022621 |
| 20111206141445 |
| 20111206141755 |

All of my migration files had the versions from 2015. So I needed to change these values. And I did it by simply running the following command a once for each entry.

mysql> update schema_migrations set version='20150205145024' where version="20111201141509";

The Secret Life of Machines

I'm very grateful to someone for posting all the episodes of The Secret Life of Machines online. I LOVED this show when it was first on. A while back I actually looked to buy a dvd of the shows and couldn't find it. This makes me so happy!

The Secret Life of Machines

In the vacuum cleaner episode, Tim builds a magnet with a battery, nail and some wire. I remember doing that exact same thing just to prove to myself that it worked. I've also used that same demonstration with my nieces and nephews.

Macs and Linux

At work, we have a bunch of computers running linux and hosting disks that are shared using NFS. Of late, many people have been switching to Macs as their primary computer. Usually, they then just ssh into one of the linux machines and work as before. However, now I think they'd like to be able to stay on their Mac and still access the files in linux. Macs are unix-based, so mounting NFS drives isn't that much of a problem. However, the default user ID and group ID used on the Mac does not match up with our uids and gids in linux. The default (first) user on a mac, is give UserId = 501 and GroupID = 20. This group id corresponds to the group named staff. I wanted to change these ids so they match up with the ids we use in linux. Then, when the user creates a file on an NFS drive, they'll have the correct owner and group. How to do this? The dscl command on the mac is the one to use.

First, I created a second administrator account on my computer and logged in as that one. I didn't try it, but I don't think that you should change the uid and gid of the user that you're currently logged in as. So I made a generic admin account, logged in as that and then ran the following.

Find out what your current settings are:

yo:~ $ sudo dscl localhost -read /Local/Default/Users/maryh PrimaryGroupID UniqueID UserShell
PrimaryGroupID: 20
UniqueID: 501
UserShell: /bin/bash

This is my account on my laptop. Say I wanted to change things to match the username and account on our linux systems. On those, my uid = 1170 and my default group is "support" with gid = 2002.

First, I'll create the support group.

yo:~ $ sudo dscl localhost -create /Local/Default/Groups/support gid 2002

Next, I'll change my PrimaryGroupID to this new group.

yo:~ $ sudo dscl localhost -change /Local/Default/Users/maryh PrimaryGroupID 20 2002

Lastly, I'll change my UniqueID.

yo:~ $ sudo dscl localhost -change /Local/Default/Users/maryh UniqueID 501 1170

The final thing that I need to do is to change the ownership of all my files in /Users/maryh because they're still owned by uid=501 and gid=20.

yo:~ $ sudo chown -R maryh:support /Users/maryh

That's it.

One other command that might be needed is to add users to a different group. Say there was another user on my laptop, arthur and I wanted him to be in the support group as well. I'd run this:

yo:~ $ sudo dscl localhost -append /Local/Default/Groups/support GroupMembership arthur

Here we want to use append because if we used create again, we'd overwrite the original group.

I want to use the automounter to automatically mount disks as needed. I could then open a terminal and cd /cdf/s1 and if /cdf/s1 wasn't mounted, it would automatically be done. The first file that I'll set up is in /etc/auto_master. I've added the following:

# Automounter master map
+auto_master            # Use directory service
/net                    -hosts          -nobrowse,hidefromfinder,nosuid
/home                   auto_home       -nobrowse,hidefromfinder
/Network/Servers        -fstab
/-                      -static

# MH Additions
/cdf    /etc/auto.cdf   intr,nodev
/psec   /etc/auto.psec  intr,nodev

Basically, this says for any mounts under /cdf, the info is in /etc/auto.cdf and for any under /psec, the info is in /etc/auto.psec.

Here's a bit of what's in the /etc/auto.psec file.

# Directory         Location

home            psec:/local/home
data1           psec2:/local/data1

This just says that to mount /psec/home, the disk is on the computer called psec. And for /psec/data1, the disk is on psec2.

The last thing that I had to do was to change the AUTOMOUNTD_MNTOPTS option in /etc/autofs.conf. Mine now looks like this:


I just had to add resvport because we have some very old linux servers that use a reserved port for NFS.

Then, I just restarted the automounter and we were all set.

yo:~ $ sudo automount -vc

Note: If you get an "Operation not permitted" error when you try to change to an automounted directory, reboot the computer.

Unexpected Time Off

We had a bit of a storm here yesterday.


That's 19" of snow in my backyard. As a good resident, I got up really early and shoveled my and my neighbors' sidewalks. But then realized that few other people had shoveled and my street had yet to be plowed. So I made the executive decision to not schlep to the bus stop (which would also have a lot of snow) to wait for one of the two buses that would take me to work.

Instead it's back to work on my wood. I thought I'd give a little overview of the process I follow. I have a big pile of wood that looks just like this.


I basically bring in about five armloads of lathe. I then trim both sides to give me a nice clean cut on the ends and roughly sort the boards into four piles by size. This lets me look at the boards a bit more closely and to throw out any that are in awful shape.


This picture shows my sorted piles as I started sanding. The furthest pile away has already been sanded.

Here all the piles of wood have been sanded. It probably took me a couple of hours to do all the pieces. It's not too hard, though my arms do get a bit tired. However, it is very loud and pretty dusty. So I wear a mask, googles and hearing protection while doing this.


Then, I just start gluing pieces together. Here's probably the widest board I'm making.


The last steps on this board will be to trim the sides and then plane it until it's smooth. This sounds easy, but it's not quick. It'll take a number of runs through my planer to get it done.