During my first months at Springest, as a fast-learning junior developer, I will be diving into the workings and usage of popular gems and posting here my experiences with each of them once in a while. Simple Form is the gem of this week!
Forms are essential for user input in web applications. However, they can become tedious to write and maintain because of the need to handle form control naming and its numerous attributes.
That’s where the Simple Form gem comes in handy. It aims to be as flexible as possible while helping you with powerful components to create your forms. And don’t worry, because you will still be able to define your layout the way you do now.
What We Are Building
In this article we will be building a model-centric form for creating and editing companies including the following fields: a
text fieldfor its name, a
text areafor its description, a
select boxfor its size (number of employees) and a
checkboxes collectionfor its different categories.
Defining Relationships Between Models
To be able to build this form we will first need a
categorymodels. Beside these two models we will also have a
characterizationjoin model, which will be in charge of connecting the
categorymodels. Any particular row in the
characterizationstable will effectively join a row in the
companiestable and a row in the
Check out the following diagram showing the models associations:
The following code shows the corresponding validations and how the structure would look like:
Let’s Build the Form
The form will be scoped to the
companymodel and to start using Simple Form you just have to add the helper it provides:
Adding a Text Field and a Text Area
When using the Rails Form Builder you need to specify one by one the type for each of the different form helpers and add a corresponding label to them. For the
text areafields you then have to pass in the name of the attribute to be called on the
companyobject (name and description in this case).
One of the nicest things about Simple Form is that you don’t need to specify the type of the different form elements, but it will figure that out by itself looking at the column type in the database and use an appropriate input for the column. For example, a column created with type
:textin the database (like the company’s description in our case) will use a
textareainput by default. You can check here a complete list of the available input types and defaults for each column type.
A label element will also be added by default to each of the fields, transforming the above code into this:
Adding a Select Box
In the case of a select box, Rails Form Builder will also need the options array to be passed in as a second parameter.
With Simple Form if you want to create a select containing the different sizes of a company you can do it overriding the
:collectionoption. Collections can be arrays or ranges, and when a
:collectionis given the
:selectinput will be rendered by default, so no need to pass the
Adding a Checkboxes Collection
To generate a collection of checkboxes with Rails Form Builder we will need to pass in the following parameters to the form helper:
- Name of the attribute or method to be called on the
companyobject (as in the previous form elements)
- Options array or collection to be shown
- Name of the attribute to be used as the checkbox value
- Name of the attribute to be used as the checkbox label text
To deal with these type of associations, Simple Form can generate either select inputs or a series of radios buttons or checkboxes. We will only need to pass in the
categoriescollection as a parameter. The association helper would render a
:selectinput by default, which can be changed into radio buttons or checkboxes like we did in this case:
What We Got
Our form will end up looking very short and simple indeed ☺ :
If you didn’t have enough and you are actually interested in doing more complicated things with Simple Form, you will be happy to hear that:
- You can create your own custom inputs
- You can also add some extra helpers
- And it works nicely with the country_select gem
- Name of the attribute or method to be called on the
Elastic Beanstalk offers a lot of bang for your buck. Deployment, auto scaling, load balancing and database management are just some of the features Elastic Beanstalk offers out-of-the-box.
It’s hard to find a software platform that isn’t supported by Elastic Beanstalk, it currently offers support for Ruby, PHP, Python, Java, .NET, Node.JS and Go. But it doesn’t stop there, for every platform there is a multitude of platform versions and servers to run your application. Just for the Ruby environment you can choose between several versions of Ruby in combination with Passenger or Puma.
But it doesn’t stop there! Elastic Beanstalk has one more trick up it’s sleeve: The ability to run your application inside a Docker container.
There are a lot of advantages to using Docker for running your application. A very incomplete list:
- Less overhead on the environment running your application.
- Test and run your application in the same environment.
- Easy to debug. You can export a faulty container, download it and start it locally.
- Simplify configuration, less need for customising the host environment using .ebextensions.
- Faster deployments and auto scaling.
We had been experimenting with using Docker to run our stack for a while. Our first try was using Deis to run our staging environment. We saw a lot of potential and spent quite a lot of time on getting our stack to work but, in the end we simply didn’t feel comfortable with the level of stability Deis was offering.
This made us little weary of trying it again on Elastic Beanstalk but, after some initial experimentation we were sold!
If you are interested in knowing more about our experiences using Deis please let us know in the comments. If we receive enough interest we might devote an article to the subject.
There’s more than one way to go about deploying an application on an Elastic Beanstalk Docker environment. First of all, you have the choice between running a single or multi-docker container setup. For our purpose the Single Docker setup works just fine.
First, we are going to need a base docker image that we can use for our deployments:
You should of course replace
awesome_appwith the name of your own organisation on the Docker repository.
Next we will create the
Dockerrun.aws.jsonfile. This file holds the configuration needed for Elastic Beanstalk to deploy your Docker container:
The file includes the following sections:
AWSEBDockerrunVersion- Specifies the version number. 1 for single and 2 for multi.
Ports- Which ports to expose on the Docker container.
Volumes- Which volumes should be mounted from host to the Docker container.
Logging- Where to mount the host log directory to the docker container. The host log directory can be found here:
If you are already familiar with the structure of the
Dockerrun.aws.jsonyou might notice we left out the
Imagesection. The above
Dockerfilewill be used as a base for a Docker image that will be built during deployment by Elastic Beanstalk. For this we need to create a different Dockerfile which will be sent along with all other application files to Elastic Beanstalk during deployment.
Create the following
Dockerfileand place it in
In this example we start the application by running
pumabut you could just as easily start any other application server.
For the final step we will need to pull it all together. We will be deploying from inside the
awesome-app/base:0.1docker container. For this we will create a simple script called
In the example the EC2 region has been hardcoded to
eu-central-1but this can be changed to the region of your liking.
The script creates two files needed by the Elastic Beanstalk CLI to deploy your application:
- .elasticbeanstalk/config.yml - This file specifies the target environment for deployment
- /root/.aws/config - This file specifies the AWS credentials file needed for authentication
For the script to work it will need two environment variables:
These can be generated from the IAM console in your AWS console.
Don’t forget to make the script executable:
Finally, let’s run the script. First we will need to start a new docker container based on the
If everything went as planned you should be logged into the docker container as root.
To run the script we first have to
/webappdirectory so we can run the deploy script:
When the script is finished your application is pushed to Elastic Beanstalk for propagation to your EC2 instances, shaving a lot of time on spinning up new EC2 instances during auto scaling.
Even though running the deployment from your local machine works perfectly fine, it would be a lot more efficient to let your CI environment take care of this. At Springest we use Wercker and their Ewok infrastructure to run our specs and deploy script.
This article won’t go into detail how Wercker can be used to make the process even more efficient. If you are interested in the details please leave a comment. If we receive enough interest we might devote an article about it in the future.Read more
Note: This project is no longer maintained by our team, but it’s still cool to learn from. If you would like to take it over, email us, or check out one of its maintained forks.
Amazon’s Elastic Beanstalk is a very nice platform to easily host simple applications, while it also gives you enough tools to customise your environment for more complex setups. One simple customisation we made here at Springest is a script to push deploy notifications to NewRelic, AppSignal, and our development Slack channel.
Example Script for Slack
For argument’s sake, we are going to use the Slack script as an example. The other scripts you can find in our repo.
Below is an example script to post to Slack. It takes a couple of arguments. Read the usage info for more details. Note that this was heavily inspired by the scripts from @apancutt’s deploy notification script.
Create a Webhook Integration in Slack
First off, you need to create a webhook integration in Slack. You can do so by clicking the name of the channel you’re in and select Add a service integration.
Create a file in
script/slack_deploy.shwith the code below and make it executable with
chmod +x script/slack_deploy.sh:
When you try to use the script above, it will fail with a:
So let’s fix that.
Creating the REVISION file
AppSignal and Newrelic need a revision for best results, so we’re going to create one. We don’t have access to the git history directly while we run these scripts on EB, so let’s make sure they get created while we have it.
You can either (1) update the REVISION file before you deploy with
eb deployor (2) have your CI / deploy tool (we use Wercker) write and commit the file. Either way, this is the command to update the file:
You can find the above script, and the scripts for NewRelic and AppSignal in the repository we created for it. Let us know if you have any fixes or improvements!
Running the scripts during deploys
To run the script, you need to tell EB which command to run. Additionally, you’ll want to make sure that it only runs once per deploy, and not on every instance (no need to have 40 deploy messages if you have 40 instances running your web cluster ;)
So we’re going to use
container_commandsfor that. Create a file called
.ebextensions/003_notifications.configand provide the following input:
Setting the necessary ENV vars on Elastic Beanstalk
As you can see from the example above, we use a couple of environment variables to call these scripts. To set these you can just use the
ebcommand line tool:
If all goes well, you will see the notification in Slack:
Back in 2002 I went to college and studied architecture. At that time pursuing a career in tech did not cross my mind.
After graduating college I worked as an architect during 5 years and in different countries. During that time I saw how some of the projects I worked on were built, such as a community-centre in Belgium, an office building in China or a private house in Amsterdam.
The similarities of Architecture and Software development
I consider the latest from those projects to be a great example of Data Oriented Architecture (I did not know back then that this term was used somewhere else ☺). The clients, a young couple expecting a child, were closely involved in the design process, which allowed for comprehensive research and understanding of how they behave and use their daily spaces.
The project started by collecting important data. To fully comprehend their behaviors and use of their living space each of them were asked to describe a perfect day in their ideal house. Using their stories we mapped their personal belongings (such as their cats toys, his large number of t-shirts or her great boots collection) and domestic rituals (shower towels, laundry clothes or kitchen cluttery). We asked the clients to place all of them on top of the floorplan specifying the location where they would be stored/used.
For those who are curious, you can read more here about the project.
Through this example you can see the surprising similarities between designing a house and a web application, in which client’s behaviors are only replaced by user’s flow.
The Scary Decision to Quit My Job
Those years were fun. But in the middle of it I started to date my husband. This is when things started to change. He is a programmer, although he is not into web development, but he works in the games industry. He is very passionate about what he does and that made me extremely curious.
We started to have more and more conversations about programming, using weird words like arrays, methods, classes, inheritance… Until I was totally trapped and decided to give it a try.
It was July 2013 when I did it. I quit my job as an architect. It was quite scary!
Why I Didn’t Go Back to College
Let’s go back to college. This was my first thought. I started to look for computer science universities searching some source of inspiration. I filled in the application form for one of them and ordered some of their books… But the moment I opened them I knew it. That was not for me.
I wanted to work in the web industry. Back then I didn’t know yet if it would be in the front-end or back-end side. But anyway what I saw in those books did not have anything to do with it.
At last I asked google, who gave me thousands and thousands of online resources to choose from. It was overwhelming and I did not know where to start. So I took the time to play around with most of them. Finally I decided to do it as follows.
How Combining Online Learning Sources Helped Me Get There Faster
I first went to Treehouse and joined one of their tracks. For those of you who are not that familiar with their website, if you visit them they have different tracks based on what you want to become. I chose to become a PHP developer, as they were the most wanted people in Germany, where I was living at that moment.
Treehouse turned out to be great to have the big picture, and understand how all the parts were coming together.
Code School was very good to dive deep into each of the topics.
And in Codecademy they make you write down a lot, which was perfect to nail down concepts.
You can also check here a complete list of the courses I followed.
5 Tips To Stay on Track
During that time I discovered other things to be as important as following these courses.
Find a partner
The first one, I had a partner. I had someone to talk to, even if he was not an expert in that technology. Which was specially important in those days when my code was broken…
Watch Tech Talks
This is something that I discovered half of the way: watch Tech Talks. I used to watch one talk per day, most of the times during lunch. It helped me to keep the motivation up. Again, at Treehouse there are a lot of them. Totally recommended!
Start a Pet Project
This one was crucial. What you build is definitely not important. But once you have some knowledge, starting a pet project is the best way to keep learning. In my case I found a person online interested to build a web application. He was preparing for a big exam and the site would help him with that. He needed to introduce new topics, questions and their answers. I learned A LOT with this project.
Breath In & Keep Coding
This one took me a little bit more time to get. When something doesn’t make sense and you try and try and still nothing… leave it. Just keep going. If you hang in there for too long you might lose your motivation. And surprisingly one day, when you do not expect it, you will get it!
Keep an Eye on Job Opportunities
And the last one, keep an eye on job opportunities. I used to have dark moments every Sunday evening. I wondered whether I was learning something that people were asking for. And that’s when I was checking jobs descriptions.
Life As A Web Developer
Four months after I started this whole process, I saw a job offer for an internship. I had studied everything that they were asking for. So I applied for it and two weeks later I was already working there. After a month in the company, they promoted me to a junior developer.
That’s the story about how I landed a job in tech.
Recently I moved from Frankfurt to Amsterdam, having to leave my job there as a PHP Developer. During my first month in the city I was actively attending Meetups, where I met an experienced developer who convinced me to learn Ruby on Rails. My approach to learn it was quite similar and some weeks later I was having my first interview at Springest. I have been working with them for one month already and I am impressed about their way to encourage people to develop themselves both personal and professionally, not only through their site but also within the company.
Starting to code was just the beginning of a long journey. As a developer you need to keep learning new things constantly. Online resources are still the best option for me, along with the awesome web community and people you work with.Read more
Today we took another step in making our data more complete by adding support for SOI (Standaard Onderwijsindeling) codes. The SOI standard has been developed by the CBS (Centraal Bureau voor de Statistiek, Statistics Netherlands in English). The goal of SOI is be a detailed coding standard by course level and subject. It is updated annually to reflect changes in the market.Read more
subscribe via RSS