29
Fri, Nov
0 New Articles

TechTip: Riding the Rails, Part 2

Scripting
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Go further into the Rails generators and Convention over Configuration. It just keeps getting better. Saving time never felt so good.

In the January 2016 article "Riding the Rails, Part 1," I introduced you to how a Rails project is created. We walked through the various files and directories that were generated. We also made it through starting the Rails web server and ended with being able to see a "Hello World" type of screen. In this article, we'll pick up where we left off by generating a Create, Read, Update, Delete (CRUD) application.

We'll be using the rails generate scaffold command to create the CRUD application. The Rails Guides documentation describes scaffolding as follows:

A scaffold in Rails is a full set of model, database migration for that model, controller to manipulate it, views to view and manipulate the data, and a test suite for each of the above.

The CRUD application will be for maintaining a very simple customer table with columns for first/last name and address. Below is the rails generate scaffold command being run and the corresponding output.

$ rails generate scaffold customer first_name:string last_name:string address:string city:string state:string zip:integer

     invoke active_record

     create   db/migrate/20160130001913_create_customers.rb

     create   app/models/customer.rb

     invoke   test_unit

     create     test/models/customer_test.rb

     create     test/fixtures/customers.yml

     invoke resource_route

       route   resources :customers

     invoke scaffold_controller

     create   app/controllers/customers_controller.rb

     invoke   erb

     create     app/views/customers

     create     app/views/customers/index.html.erb

     create     app/views/customers/edit.html.erb

     create     app/views/customers/show.html.erb

     create     app/views/customers/new.html.erb

     create     app/views/customers/_form.html.erb

     invoke   test_unit

     create     test/controllers/customers_controller_test.rb

     invoke   helper

     create     app/helpers/customers_helper.rb

     invoke     test_unit

     create       test/helpers/customers_helper_test.rb

     invoke   jbuilder

     create     app/views/customers/index.json.jbuilder

     create     app/views/customers/show.json.jbuilder

     invoke assets

     invoke   coffee

     create     app/assets/javascripts/customers.js.coffee

     invoke   scss

     create     app/assets/stylesheets/customers.css.scss

     invoke scss

     create   app/assets/stylesheets/scaffolds.css.scss

Let's dissect the command that was run.

First, we have the rails command. It's important to know that each level of these commands has its own "help" to gain insight about the syntax. For example, here are the commands to run to get help at each of the levels:

$ rails --help

$ rails generate --help

$ rails generate scaffold --help

The scaffold portion of the command requires we pass the name of the model as the first parameter, in this case customer. The "model" is what communicates to the DB2 table and also where we can store additional code relating to customers (business logic). After the model name come the columns and their data types, separated by a colon. The data types of string and integer correlate to data types in the ActiveRecord ibm_db adapter, maintained by IBM and KrengelTech as an open-source project on Bitbucket. You can see the specific lines of code doing the correlation here.

Going back to the output, created first is db/migrate/20160130001913_create_customers.rb, which holds what's called a database migration, a way to record the changes needing to be done to the database. We will be covering database migrations in a subsequent article.

Next we see file app/models/customer.rb created, shown below.

---- app/models/customer.rb ----

class Customer < ActiveRecord::Base

end

As you can see, there isn't much to it. That's the beautiful part! This is Convention over Configuration, discussed in the first article, at its best. When we start the Rails server, it will make a query to the DB2 customer table, asking for the column meta data. It will then dynamically insert code into the customer.rb model so we can access each column. This is called Ruby open classes. It’s a phenomenally powerful feature because it keeps you from having to manually enter and subsequently maintain code in the model. In short, a very big timesaver.

Next in the output, we have test/models/customer_test.rb and test/fixtures/customers.yml that are created for unit testing purposes. The goal is for every time you create a method in app/models/customer.rb, a unit test in test/models/customer_test.rb should also be created. Every time someone doesn't write a unit test, a politician lays an egg. So let's write some unit tests!

Next in the output, we have resources :customers being added as what's called a route. This means that line was added in the config/routes.rb file to configure how inbound requests should be mapped to your Ruby code. Think of this as being similar to an RPG green-screen program that needs to route processing based on the key a user selects. So if the user presses the F4 key, you would EXSR to CUSTPRMPT, for example. More on routing in future articles.

Next in the output, we have app/controllers/customers_controller.rb which is the controller. The controller facilitates deciding what should be done based on the user's input. For example, when a user submits an HTML form to add a customer row to the database, the controller will receive in the form, call on the validation routines, and, depending on the validation success or failure, redirect the user accordingly.

Next in the output we have the views, as shown below.

app/views/customers/index.html.erb

app/views/customers/edit.html.erb

app/views/customers/show.html.erb

app/views/customers/new.html.erb

app/views/customers/_form.html.erb

The views are similar in nature to *DSPF DDS in RPG. It's where screen definitions are defined. But here, HTML is used instead of DDS. As you can see, there are five different files, each serving a CRUD purpose. File index.html.erb displays a listing of existing customers. File edit.html.erb shows a form to edit an existing customer. File show.html.erb is for (you guessed it) conveying a customer's information in read-only fashion. File new.html.erb is for creating a new customer. The last one, _form.html.erb, is what's called a "partial." Partials are named with an underscore as their first charactera convention of Rails. A partial is a lot like a copy book in RPG: a way to modularize code for reuse in other source files. In this case, _form.html.erb is used in both edit.html.erb and new.html.erb because they both need to display the same HTML form fields, just in a different scenarioediting a customer vs. creating a new one.

Next in the output, we have test/controllers/customers_controller_test.rb, which is another unit-testing skeleton, this time for the controller portion of the customer CRUD application.

Next in the output, we have app/helpers/customers_helper.rb, which is a place to put code that doesn't necessarily belong in the model layer (because it has to do with the view layer). You don't want to put it into the view layer because it would just muddy the code and make it hard to read. For example, let's say you wanted to display a customer's credit in red if they were nearing the danger zone. Something like that would go in a helper because you wouldn't want HTML in your model. You also wouldn't want the "if" statement logic muddying up your view layer.

Next in the output, we have app/views/customers/index.json.jbuilder and app/views/customers/show.json.jbuilder, which are used to offer up the same data as a normal HTML view but instead as a JSON response. For example, if the browser invokes URL http://domain.com/customers, it will return an HTML listing of customers. But if the browser invokes URL http://domain.com/customers.json, it will return a JSON listing of customers. No logic on the server side needed to change. This is obviously great for when you need to offer web services (e.g., AJAX requests from the browser).

Last up in the output, we have app/assets/javascripts/customers.js.coffee and app/assets/stylesheets/customers.css.scss. These are used to store your coffee scripts and sass scripts, respectively. To be honest, I don't use coffee script that much and instead prefer raw JavaScript. Sass on the other hand has seemingly caught on better in the broader web community (e.g., the popular UI framework BootStrap uses it) so I do use that. Coffee script essentially makes JavaScript more concise to write. Sass is an extension to CSS where CSS lacks certain features like variables, modularity for reuse, etc. This is definitely necessary as CSS continues to grow in complexity and prominence. The coffee script and sass are converted to JavaScript and CSS before they're sent to the browser.

OK, now it's time to see the app that was created with the rails generate scaffold command. Use the rails server command to start the server, as shown below. The -p60128 is specifying a specific port if you don't want the default of 3000.

$ rails server -p60128

NOTE: Make sure you are in the root of the Rails project's folder when you are running rails commands.

Now open your browser and enter the IP address of your IBM i and the port you specified, and you should see the error shown in Figure 1.

 

021216Bartell-Figure1-rakedbmigrate

Figure 1: Pending database migrations

This error is conveying another very cool feature of Ruby on Rails. When we started the server, it made an SQL query to table SCHEMA_MIGRATIONS to check and see if there were any migrations in our application folder db/migrate that hadn't yet been invoked on the database. In this case, it recognized that database migration 20160130001913_create_customers.rb hadn't yet been run and informed us accordingly in the browser error. To remedy the issue, we can run the below rake db:migrate command.

$ rake db:migrate

== 20160130001913 CreateCustomers: migrating ==================================

-- create_table(:customers)

   -> 0.3369s

== 20160130001913 CreateCustomers: migrated (0.3371s) =========================

The rake db:migrate command does the same SQL query to SCHEMA_MIGRATIONS to check for migrations that need to be run. We can see it found the CreateCustomers migration and executed it against the database, effectively creating the CUSTOMERS table with an SQL CREATE TABLE statement.

Now start the Rails server again and direct your browser to http://ibmi_ip:port/customers to see the result in Figure 2.

 

021216Bartell-Figure2-customerlisting

Figure 2: Customer listing page

By specifying /customers in the URL, and given the entry in routes.rb, the Rails web server knew to route the request to the index Ruby method in the customers_controller.rb file, as shown below.

def index

   @customers = Customer.all

end

What you see above is Ruby code that's making a request to DB2 using the following SQL syntax.

SELECT customers.* FROM customers

What's interesting about the index Ruby method is it doesn't declare what HTML file should be conveyed back to the browser. This is "Convention over Configuration" happening again. If you don't specify a specific HTML file to render the results, then Rails will use the default. The default is to look for a file with the same name as the method (e.g., index.html.erb) in the folder with the same name as the controller (e.g., app/views/customers). This was initially frustrating to me because I came from a more raw RPG-CGI background where I had to do everything. I've grown to greatly appreciate these various conventions because they really do save time.

Select the "New Customer" link and you will see the screen in Figure 3.

 

021216Bartell-Figure3-newcustomerform

Figure 3: Add a new customer

Notice the "/new" portion at the end of the URL? Again, that helps Rails to know which controller method to route this request to. If you look inside customers_controller.rb, you can see it has a new Ruby method. We won't digress into that right now, but know Figure 3 is the new.html.erb file being rendered in the browser, using the _form.html.erb partial for the form.

Filling out the form and selecting the "Create Customer" button produces the screen in Figure 4.

 021216Bartell-Figure4-displaynewcustomer

Figure 4: Showing the created customer

File show.html.erb is used to convey the page in Figure 4. You'll notice the "/1" at the end of the URL. This is the unique surrogate (not composite) key for the CUSTOMERS table.

Selecting the "Back" link will take you back to the customer listing, as shown in Figure 5.

021216Bartell-Figure5-customerlistingwithdata

Figure 5: Customer listing with data

I could go on further, but eventually this article needs to end. Right?

There's so much more to cover from what was created with the rails generate scaffold command. We’ll pick up where we left off in next month's article.

If you have any specific questions please let me know in the comments or reach me directly at This email address is being protected from spambots. You need JavaScript enabled to view it..

Aaron Bartell

Aaron Bartell is Director of IBM i Innovation for Krengel Technology, Inc. Aaron facilitates adoption of open-source technologies on IBM i through professional services, staff training, speaking engagements, and the authoring of best practices within industry publications andwww.litmis.comWith a strong background in RPG application development, Aaron covers topics that enable IBM i shops to embrace today's leading technologies, including Ruby on Rails, Node.js, Git for RPG source change management, and RSpec for unit testing RPG. Aaron is a passionate advocate of vibrant technology communities and the corresponding benefits available for today's modern application developers. Connect with Aaron via email atThis email address is being protected from spambots. You need JavaScript enabled to view it..

Aaron lives with his wife and five children in southern Minnesota. He enjoys the vast amounts of laughter that having a young family brings, along with camping and music. He believes there's no greater purpose than to give of our life and time to help others.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: