Tuesday, December 31, 2013

Quick simple Rails form

Here's a very quick and very simple Rails form.  I am pulling this from this Youtube tutorial, but documenting the actual steps needed because I find it easier to read and newer versions of Rails require that we do things a little differently than what is described in the video.

cd rails_projects
rails new simpleform
cd simpleform
rails g controller students
rails g model Student firstname:string lastname:string
rake db:migrate
cd db
sqlite3 development.sqlite3
.schema
.quit
cd ..

Change app/controllers/students_controller.rb from this:

class StudentsController < ApplicationController
end




To this:

class StudentsController < ApplicationController
  def new
    @student = Student.new
  end

  def create
    @student = Student.new(params[:student])
    if @student.save
      redirect_to new_student_path
    end
  end
end




Create new file app/views/students/new.html.erb:

Enter new student information
<hr>
<%= form_for @student do |f| -%>
  Firstname: <%= f.text_field :firstname %><br />
  Lastname: <%= f.text_field :lastname %><br />
  <%= f.submit %>
<% end -%>


Insert the resources line into config/routes.rb:

Simpleform::Application.routes.draw do
 

  resources :students



Start up the rails server to see how things look thus far:
rails s

Point your browser to http://localhost:3000/students/new

This shows you a simple form with text fields for firstname and lastname.  Enter in some text for the two fields and click the submit button.  You will get an error:

ActiveModel::ForbiddenAttributesError in StudentsController#create
ActiveModel::ForbiddenAttributesError
Extracted source (around line #7):
@student = Student.new(params[:student])

I think it has to do with security and probably a change that happened in Rails versions. 

Here's the fix.

Change app/controllers/students_controller.rb:

class StudentsController < ApplicationController
  def new
    @student = Student.new
  end

  def create
    @student = Student.new(user_params)
    if @student.save
      redirect_to new_student_path
    end
  end

  private

   def user_params
     params.require(:student).permit(:lastname, :firstname)
   end


end



Now point your browser to http://localhost:3000/students/new
and try to enter a couple records.

We can view the new records in our database:

cd db
sqlite3 development.sqlite3
.schema
select * from students;
.quit
cd ..



So we are successfully inserting data into our database!  Hurray!

Now we will make a couple changes so our web page not only gathers student names, but displays them as well.

Append the following lines to app/views/students/new.html.erb:

<hr>
Display all students' information<br />
<% if !@students.blank? %>
  <% for item in @students %>
    <%= item.firstname %> <%= item.lastname %> <br />
  <% end %>
<% else %>
<% end %>



We also have to define @students in app/controllers/students_controller.rb:

  def new
    @student = Student.new
    @students = Student.find(:all)
  end


Rails Tutorial using mysql

So I am reading this Rails Tutorial a second time, this time doing some off-roading.

[Edit 2015-12-15 - Reader "Zane" was kind enough to let me know the link was busted. Looks like a new edition was released and can be seen here.  Another tutorial can be viewed here.]

To start a project using mysql (instead of mysqlite), do this:

rails new app_name -d mysql

I am running OSX with a mysql image downloaded from Oracle.  When I tried to run this command:

rails generate scaffold User name:string email:string

The command failed with:
Library not loaded: libmysqlclient.18.dylib (LoadError)

Here is the fix:
sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib

The tutorial next has us run:

bundle exec rake db:migrate

Which results in this error:

rake aborted!
Access denied for user 'root'@'localhost' (using password: NO)

The fix is to edit your config/database.yml file:

Scroll down and replace update username: and password: values appropriately.

Re-running the command above yields:

rake aborted!
Unknown database 'app_name_development'

The fix is to create a new database:

rake db:create

Now the bundle exec command attempted above will work.

We can confirm this worked by interacting with the demo app and running the following commands:

mysql -u root -p
show databases;
use demo_app_development;
show tables;
select * from users;





Monday, December 30, 2013

Safari Extension - ZoomBySite - Set and remember zoom levels for individual web sites

This method initially worked OK but I found some problems with it.  For example, when composing a new email via gmail I could not see the "Send" button.  No good!

So I turned that off and am trying this extension instead: ZoomBySite

ZoomBySite is a Safari extension that:

1 - Lets you set a default zoom level for all sites
2 - Remembers a customized zoom level for specific sites


Sunday, December 29, 2013

Better fonts and colors in OSX Terminal

Open a Terminal session.

Terminal | Preferences | Settings | Homebrew
Font | Change
English | Menlo | Regular | 14
Default

Saturday, December 28, 2013

Part 2: How to install Rails and MySQL in Mavericks OSX

[Continued from Part 1: How to install Rails and MySQL in Mavericks OSX]

In Part 1, we installed Xcode, Homebrew, RVM, MySQL, and upgraded to the latest stable release of Ruby.

In Part 2, we install Git, Github, Gems, and Rails.

Install and configure Git

brew install git

I followed my Git notes here


Github


Generate SSH keys

While following the guide above, I set up a repository at Github called project1 to match the local repository I had previously initialized.  The only purpose of "project1" was to set up and test Github connectivity.

Set up GitHub repository

cd to the project1 subdirectory and run the following commands:

touch hello.txt
git init
git add .
git commit -m "first commit"
git remote add origin git@github.com:<yourusername>/project1.git
git push -u origin master


Now that we know we can push to Github, we can remove the test files.  Remove project1 from both the local host and Github.

Gems


rvm install ruby
rvm use ruby --default
rvm rubygems current

This bumped me up to Ruby 2.1.0 and installed rubygems (among other things).

Rails

And - FINALLY - install Rails:

gem install rails




Friday, December 27, 2013

Set a default zoom level for Safari

[Edit: There is a better way - ZoomBySite]

This will tell Safari to automatically zoom in (make bigger) on all web pages.  If you find yourself pressing CTRL + frequently, give this a try.

Create a file named defaultzoom.css 

Insert this text:

body {
zoom: 130%;
}

Change 130 to whatever works for you. 
>100 means zoom in (make bigger)
< 100 means zoom out (make smaller)

In Safari, go to Preferences | Advanced
Under Style sheet, select Other and point to the file you created.

I ran across this tip here.

Part 1: How to install Rails and MySQL in Mavericks OSX


Install Rails

My buddy Mark Moser sent me to Andrew Kennedy's helpful blog so I could install Rails on my new MacBook (OSX Mavericks). My install did not quite follow Kennedy's documentation exactly so I've detailed below what works for me.

Install Xcode from the App store.

Run Xcode to initialize stuff.  I failed to do this the first time and I think it caused my Homebrew install (we do this later) to fail.

Install the command line tools:

xcode-select --install

Install Homebrew.  "Homebrew installs the stuff you need that Apple didn’t."  

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

Install RVM.  RVM is Ruby Version Manager.  I think this lets me install and run multiple environments (Ruby versions and collections of gems).  The first time I tried to install rvm, the script complained and told me:

RVM PATH line not found for Bash, run the installer with '--auto-dotfiles' to fix it.

So I installed RVM like this:

curl -L https://get.rvm.io | bash -s stable --auto-dotfiles

The script gives this warning:

  * WARNING: You have '~/.profile' file, you might want to load it,
    to do that add the following line to '/Users/<username>/.bash_profile':

      source ~/.profile

I could not install the requirements (the next step) without sourcing the .profile (above).  

[Note to self: next time, insert this into my .bash_profile, exit the terminal, and then open a new terminal before proceeding.]

Install rvm requirements.  This figures out additional stuff needed and installs it - autoconf, automake, libtool, pkg-config, gcc46, libyaml, readline, libksba, openssl

rvm requirements

Note that this took a very, very long time and seemed stuck like this for an hour (crazy, right?) or so:

Installing required packages: autoconf, automake, libtool, pkg-config, gcc46, libyaml, readline, libksba, openssl........

The man page for rvm says this about requirements:

Show additional OS specific dependencies/requirements for building various rubies.

The thing that's weird about this is I think it installs these requirements; I don't think it only shows (displays) them.

Since we made changes, now we need to reload rvm:

rvm reload

Make sure we are running the most current stable version of rvm:

rvm get stable

Kennedy's blog guides us to install Ruby version 2.0.0.  I was already running ruby 2.0.0p247.  We can determine version info by running

ruby -v

I don't know if this version came with OSX or if I installed it during a previous session of tinkering.  Regardless, I went ahead and ran Kennedy's suggestion:

rvm install 2.0.0

RVM went out and found 2.0.0-p353 -- cool!  Notice it is slightly newer than the version I already had (p247).

I have no interest in legacy versions or enterprise edition, so I skipped those parts of Kennedy's blog.

Install mysql

Also, I chose to install mysql from MySQL.com at Mark's suggestion instead of installing it via Homebrew.

Get mysql from here to download the dmg

Open the disk image and run the mysql package.  I had to right-click and choose "Open" to get around the security feature that prevents some programs from running.

Mysql is now installed but not configured.  Time to do that.  I followed some of the documentation here and here

Add the mysql binaries to our environment path so bash can find them:

Insert the following line in ~/.bash_profile

export PATH=$PATH:/usr/local/mysql/bin

Exit the terminal session and open a new one.  The path environment variable is now set.

For the following commands to work, we need to change our directory:

cd /usr/local/mysql

Change user and group ownership so mysql is accessible to the mysql user.  Run these commands with sudo:

sudo chown -R mysql .
sudo chgrp -R mysql .

Start mysql:

sudo bin/mysqld_safe --user=mysql &

Any time you append an ampersand (&) to a bash line, you are telling bash to run this command indefinitely in the background.  So the above command runs a mysql daemon (service) called mysqld_safe as user "mysql" and runs it in the background.

This command tests mysql to see if it is running:

mysqladmin version

The system should respond with version information.

Gently shut down mysql:

bin/mysqladmin -u root shutdown

Restart mysql using the same command we used above:

sudo bin/mysqld_safe --user=mysql &

Make sure mysql is running.  The following command will display available databases:

mysqlshow

We now have mysql running but we are using default passwords.  Time to change that.  Connect to mysql as root:

mysql -u root

Note: the mysql "root" user is not the same as the operating system's "root" user. 

Display a list of users:

SELECT User, Host, Password FROM mysql.user;

System replies:

+------+-------------+----------+
| User | Host        | Password |
+------+-------------+----------+
| root | localhost   |          |
| root | myosx.local |          |
| root | 127.0.0.1   |          |
| root | ::1         |          |
|      | localhost   |          |
|      | myosx.local |          |
+------+-------------+----------+

Change the root password with the following command.  

UPDATE mysql.user SET Password = PASSWORD('YourNewPassword')
WHERE User = 'root';

Tell mysql to re-read grant (permission) tables so it will notice the password change:

FLUSH PRIVILEGES;

Confirm passwords were updated:

SELECT User, Host, Password FROM mysql.user;

The Password column will no longer be blank.

Sidenote: We could have changed the password by issuing four SET PASSWORD commands but I was lazy.  I list it here for documentation purposes - don't need to do this now:

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpwd');
SET PASSWORD FOR 'root'@'::1' = PASSWORD('newpwd');
SET PASSWORD FOR 'root'@'host_name' = PASSWORD('newpwd');

Leave the mysql session:

exit

Now when we want to connect as root, we have to supply a password.  The command below starts up a mysql session as user "root" and tells the system to prompt us for a password:

mysql -u root -p

The documentation goes over removing anonymous accounts and securing test databases.  You can read that documentation here.  I am not following it because this is my play/dev machine and I want to leave these accounts as-is.  If you are connecting a system to a network, you should probably follow the documentation and remove them.

Now we have mysql running and configured, but we started it manually.  We now need to configure mysql to start automatically.

First, leave the mysql session and shut mysql down gently:

exit
bin/mysqladmin -u root -p shutdown

Notice this time we had to tell mysql to prompt for a password (the "-p" option).  Previously, we omitted that flag because there was no password assigned to root.

I followed the documentation here.  Open up the contents of the mysql disk image file that we previously downloaded.

Run MySQLStartupItem.pkg (right-click | Open)

The installer will guide you through the process.

Once done, look in the mysql disk image file one more time.  Run (right-click | Open) MySQL.prefPane.  This will install a MySQL utility in System Preferences.  Go there to start/stop MySQL and to tell MySQL whether or not to start automatically.


[To be continued in Part 2]

Saturday, December 21, 2013

Vim - How to add contents of external file to current buffer

This will insert the contents of test.txt into the buffer directly below the cursor:

:r ~/test.txt

r = Read contents

This will replace the buffer with the contents of test.txt:

:%!cat ~/test.txt

Breaking the above command down:

% = Entire contents of buffer
! = Run an external command
cat = Concatenate (display)
~ = Home directory
test.txt = Filename

The ! (bang) command lets us run external programs from the shell.  Of particular interest, we can run commands against the Vim buffer.  For example, the command below will run a shell sort command against the contents of the Vim buffer:

:%!sort %

The first % is necessary because it tells Vim we are about to do something to the entire contents of the buffer.  Everything after the !bang is the external command.

Another (silly) example - this runs the word count (wc) command:

:%!wc %
:%!wc

More realistic examples would use various external commands to chop up the contents of the Vim buffer - commands such as cut, sed, and so on.

Note to self:  There is a subtle difference here between appending the second "%" symbol in the first command and leaving it out in the second command.  This needs further investigation.

---

Shout out to my buddy Mark Moser for sending me a one-liner and making me remember/research this!  His one liner follows.

:r! cal 2014







Sunday, December 15, 2013

gvim font style and size

Put this in your .gvimrc file:

if has("gui_running")
  if has("gui_gtk2")
    set guifont=Inconsolata\ 16
  elseif has("gui_macvim")
    set guifont=Menlo\ Regular:h18
  elseif has("gui_win32")
    set guifont=Consolas:h11:cANSI
  endif
endif

This sets the font style and size depending on which environment you are running.  For example, I am running Mac OSX so my font is set to "Menlo Regular:h18".

Select your preferred font by looking at Edit | Font | Show Fonts
To reveal what that means to gvim, run this within gvim:

:set gfn?

For example, if I use the graphical menu to select "English Andale Mono | Regular | 24", the command "set gfn?" would reveal "guifont=Andale Mono:h24"

With that knowledge, we can craft what font we need to provide in the .gvimrc file from above.  Escape spaces with a backslash, so we get:

Andale\ Mono:h24

So my .gvimrc script line would read:

set guifont=Andale\ Mono:h24


Tuesday, December 10, 2013

Mac OSX bash prompt

Put this in .bash_profile

export PS1="\w\$ "

This will considerably shorten your bash prompt to display only the working directory instead of the default which also displays computer name and user name.

We can display those as well by playing around with the defaults:

PS1='\h:\W \u\$ '

\h = First part of host name
\W = Directory name (notice this is uppercase rather than the lowercase I used above.  Lowercase w means the entire directory path; uppercase W means just the working directory)
\u = Username
\$ = If not root, display $ (otherwise display #)

There are other "magic" symbols that can be used - see http://www.ibm.com/developerworks/linux/library/l-tip-prompt/


Thursday, December 5, 2013

Turn off bells in Vim

:set visualbell

This tells Vim to flash the screen instead of ringing a bell.

To make it permanent, put it in your .vimrc file:


set visualbell



Wednesday, December 4, 2013

How to insert/remove comments in Vim

Insert comments (for example, the "#" symbol):

Go to the line you want to comment.
Press CTRL-V (might be CTRL-Q in Windows because of shortcut conflict)
Cursor to the last line
Press I, #, [Esc]
("I", then "#", then "Escape")
(Case matters.  Uppercase "I", not lowercase "i")




Remove comments:

Go to the line you want to comment.
Press CTRL-V (might be CTRL-Q in Windows because of shortcut conflict)
Cursor to the last line
Press x


How to update Ubuntu

sudo apt-get update
sudo apt-get upgrade

and sometimes

sudo apt-get dist-upgrade

Tuesday, December 3, 2013

Monday, December 2, 2013

How to reset a Rails database

bundle exec rake db:reset
bundle exec rake test:prepare


May have to restart the Rails web server.