Amazon EC2 – Query Request in Java

My day gig has been having me learn Java and using it to connect to third party providers. If anyone’s ever tried to use Amazon’s AWS APIs, you’ll understand my pain. Although there is a lot of documentation on their site, it’s always a little hard to find exactly what you’re looking for. I didn’t want to rely on one of their SDKs because I try to avoid using libraries where I can. So I spent about 2 days converting their Python code to Java (my Java knowledge is minimal).

Here’s the code that finally worked. I did away with the method, instance variables, and imports. This should get you what you need.

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
df.setTimeZone(tz);
final String amazonDate = df.format(new Date()) + "Z";
 
DateFormat ds = new SimpleDateFormat("yyyyMMdd");
ds.setTimeZone(tz);
String dateStamp = ds.format(new Date());
String canonicalQueryString = String.format("Action=%s&Version=%s", this.action, this.apiVersion);
String canonicalHeaders = String.format("host:%s\nx-amz-date:%s\n", this.host, amazonDate);
String signedHeaders = "host;x-amz-date";
String text = "";
String payloadHash = DigestUtils.sha256Hex(text);
String canonicalRequest = "GET\n/\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + payloadHash;
String credentialScope = String.format("%s/%s/ec2/aws4_request", dateStamp, this.region);
 
String output = "";
try {
    byte[] signingKey = getSignatureKey(this.secretKey, dateStamp, this.region, "ec2");
    String canonicalRequestHash = DigestUtils.sha256Hex(canonicalRequest);
    String stringToSign = String.format("AWS4-HMAC-SHA256\n%s\n%s\n%s", amazonDate, credentialScope, canonicalRequestHash);
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretkey = new SecretKeySpec(signingKey, "HmacSHA256");
    sha256_HMAC.init(secretkey);
    byte[] hash = sha256_HMAC.doFinal(stringToSign.getBytes());
    String signature = Hex.encodeHexString(hash);
    String authorizationHeader = String.format("AWS4-HMAC-SHA256 Credential=%s/%s, SignedHeaders=host;x-amz-date, Signature=%s", this.accessKey, credentialScope, signature);
    String url = String.format("%s?%s", this.endpoint, canonicalQueryString);
 
    HttpClient client = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);
    get.setHeader("Content-Type", "application/x-www-form-urlencoded");
    get.setHeader("x-amz-date", amazonDate);
    get.setHeader("Authorization", authorizationHeader);
 
    HttpResponse response;
 
    try {
        response = client.execute(get);
        HttpEntity entity = response.getEntity();
        output = EntityUtils.toString(entity);
    } 
    catch (IOException e) {
        throw new BridgeError("Unable to make a connection to properly execute the query to Amazon EC2");
    }
 
} catch (Exception ex) {
    throw new BridgeError("Unable to make a connection to properly execute the query to Amazon EC2");
}
 
JSONObject jsonOutput = XML.toJSONObject(output)

Hopefully that helps someone out!

Add React.js to an Existing Rails Application Tutorial Part 2

Welcome to Part 2 of the React.js on Rails series (see Part 1). We left off by making the upvote/downvote buttons functional and having stories be rendered on the homepage dynamically. Now, I want to go even deeper. We’re going to go over how to create stories, delete them, and make the category links show you only stories within that category.

Working Category Links

Let’s start with making our category links work. What we’ll need to do is create a function that’ll show us only relevant stories (ones that are in that category). Go to stories.js.jsx and add the handleAllCategories line to the render function.

// stories.js.jsx
.
.
<ul className="list-group">
  { this.state.categories.map(function(category){
    return (
      <Category key={ category.id }
        category={ category }
        handleAllCategories={ self.handleCategoryClick } /> //adding this line
    )
  })}
.
.

We are assigning this function to handleAllCateogories, which we’ll be putting in our Category component. We haven’t created this function yet. We also haven’t created the handleCategoryClickfunction. What we first need to do is create an endpoint to get all the stories. Let’s create a route and then an action in our stories controller.

#routes.rb
get "/all_stories", to: "stories#all_stories"
#stories_controller.rb
def all_stories
  @stories = Story.all
  respond_to do |format|
    format.json { render json: @stories }
  end
end

Add Lodash.js

Before continuing on, let’s add the lodash JavaScript library to our application. Lodash is simply a collection of helper methods that help us not write so much JavaScript (think jQuery, but actually handling data and doing stuff to it). We’ll use one of these methods later on.

  • Go to lodash.com.
  • Click on the “Modern build” link. It’ll take you to a plain HTML page that has a ton of code.
  • Select all (cmd + a) and copy.
  • Create a new file under app/assets/javascript and name it lodash.js. Paste all this code in this new file and save it.
  • Go to application.js and add //= require lodash in the commented out section. I put mine right above //= require_tree .
  • **MAKE SURE TO RESTART THE RAILS SERVER**

We’ve just added lodash.js to our application.

Going back to making our category links work, we’ll need to create the handleCategoryClick function in our stories.js.jsx file.

// stories.js.jsx
handleCategoryClick: function(category, e){
  var self = this;
  $.getJSON('/all_stories.json', function(allStories){
    self.setState({stories: allStories});
    var categoryStories = _.where(self.state.stories, { 'category_id' : category.id })
    self.setState({ stories: categoryStories.slice(0, 26) });
  }.bind(this));
},

What we’re doing is getting all the stories and finding the ones that have a category_id that matches category.id. The “_.where” method is what lodash.js is helping us with. Think of it like a Rails where method.

So we set a property of handleAllCategories for our Category component. Let’s head over there and make the click link functionality work. In the render function, we’ll want to add an onClick event.

// category.js.jsx
.
.
render: function(){
  return (
    <li className="list-group-item">
      <a href={'#' + this.props.category.name}
         onClick={ this.handleLinkClick }>{ this.props.category.name }</a>
    </li>
  )
}
.
.

What we’re doing is setting the onClick action to a handleLinkClick function. We need to create this function right above.

// category.js.jsx
.
.
handleLinkClick: function(e){
  this.props.handleAllCategories(this.props.category); // this is where we set handleAllCategories from stories.js.jsx
},
.
.

Remember when we passed in handleAllCategories from stories.js.jsx? This is where we’re setting the value to the category name.

Now go to your application in the browser. Click on the category links on the right hand side. They should go through all the stories and filter out and only show you the ones based on the category you clicked. Cool, right?!

Adding a story

We want this to be a single page application. So when we create a new story, we don’t want to have to navigate to a different page. Let’s add a form right on the home page that will allow us to create a new story.

We’re going to need to add a button and form to stories.js.jsx. To go the render function and added it right under the “container” div.

// stories.js.jsx
.
.
render: function(){
  var self = this;
  return (
    <div className="container"> // adding to this div
      <button className="btn btn-primary" id="submit_scary_story">Submit your scary story</button>
      <br />
      <StoryForm handleNewRecord={ this.addRecord } />
      <br />
  .
  .
  )
}

By now, you might have already guessed. We’re setting a StoryForm component and sending in a property of handleNewRecord. We’re setting it to an addRecord function. Let’s create this right above the render function.

// stories.js.jsx
.
.
addRecord: function(story){
  var records = React.addons.update(this.state.stories, { $unshift: [story] })
  if (records.length > 25) {
    records.pop();
  }
  this.setState({ stories: records });
},
.
.

This is updating the current state of the stories. We’re only showing 25 stories on the homepage because of pagination. In order to keep it there, when we add a new record, we need to get rid of the last one (which is what the pop() method is doing for us). So we get all 25 stories, add a new story, remove the last one, then set the state to our new 25 stories.

StoryForm Component

Let’s go create the StoryForm component.

// story_form.js.jsx
var StoryForm = React.createClass({
  getInitialState: function(){
    return {
      body: '',
      category_id: 1
    }
  },
 
  render: function(){
    return (
      <form className="new_story"
            id="new_story">
        <div className="form-group">
          <label>Tell us your scary story</label>
          <textarea className="form-control"
                    id="story_body"
                    name="body"
                    value={ this.state.body}/> // using React here
        </div>
        <div className="form-group">
          <div className="form-group">
            <label>Category</label>
            <select className="form-control"
                    id="select"
                    name="category_id"
                    value={ this.state.category_id }> // and here. Everything else is just HTML.
              <option value="1">Ghost</option>
              <option value="2">Witch</option>
              <option value="3">Monster</option>
              <option value="4">Stalker</option>
              <option value="5">Night</option>
              <option value="6">Children</option>
            </select>
          </div>
        </div>
        <button className="btn btn-primary"
                type="submit">Create</button>
      </form>
    )
  }
})

It looks like a lot is going on, but it’s actually just stuff we’ve seen before. In the getInitialState function, we’re just setting two variables, “body” and “category_id”. These are the default values. The form looks scary, but it’s really just HTML. We’re fetching the state values in our text and select fields. Right now, this is just a static form that really doesn’t do anything. We’re going to add some functions to this form so that when we click the Create button, it’ll save the data.

onChange events on our Story Form
We’ll want to create onChange events that call functions to do things with. The first one we’re going to create is for our text area. When someone is entering in their story, we want to store this in our initial values. Let’s start with the text area.

// story_form.js.jsx
.
.
<textarea className="form-control"
                    id="story_body" 
                    name="body"
                    value={ this.state.body}
                    onChange={ this.handleBodyChange }/> // adding this line to the text area
.
.

We’re saying that when this text area changes, call the handleBodyChange function. Let’s create that function right underneath the getInitialState function.

// story_form.js.jsx
.
.
handleBodyChange: function(e){
  var name = e.target.name;
  var nextState = {};
  nextState[name] = e.target.value; // creates hash like this: {"body" => "Whatever is entered in text area"}
  this.setState(nextState);
},
.
.

What we’re doing is getting the target name (in this case, it’s “body”). We’re creating an empty hash value, populating it, and then setting the state to it. We can do the same for the selected category.

// story_form.js.jsx
.
.
// this goes right after handleBodyChange
handleCategoryChange: function(e){
  var name = e.target.name;
  var nextState = {};
  nextState[name] = e.target.value;
  this.setState(nextState);
},
.
.
<select className="form-control"
                    id="select"
                    name="category_id"
                    value={ this.state.category_id }
                    onChange={ this.handleCategoryChange }> // add this line to our form
.
.

Great. All that’s left is the submit function. When this form is submitted, we need to create a function that sends the data to be saved in the database. Add an onSubmit event to our form.

// story_form.js.jsx
.
.
// create the handleSubmit function
handleSubmit: function(e){
  var self = this;
  e.preventDefault();
  $.ajax({
    method: 'POST',
    url: '/stories',
    data: { story: this.state },
    success: function(data){
      self.setState(self.getInitialState());
      self.props.handleNewRecord(data);
    }.bind(this)
  })
},
 
render: function(){
    return (
      <form className="new_story hidden" 
            id="new_story"
            onSubmit={ this.handleSubmit }> // add this line
        .
        .
    )
.
.

There’s a lot going on in the handleSubmit function. Don’t let it scare you, it’s just regular JavaScript stuff. It’s just making an AJAX POST request to the /stories URL. The “data” attribute is being set to the data of the form (body and category). If the AJAX call is successful, it’ll set the current state and handleNewRecord property to the new body/category values. Remember, the handleNewRecord property was being set in stories.js.jsx.

Before we can get this to work, we need to return a JSON value when we send the AJAX request. Go to stories_controller.rb and change the create action so that it returns JSON.

#stories_controller.rb
def create
  @story = Story.new(story_params)
  @story.user = current_user
  if @story.save
    render json: @story
  else
    render json: @message.errors, status: :unprocessable_entity
  end
end

Now try adding a record via the form. It should create a new story and add it to the top. Keep in mind, you have to be signed in to create a new story

Deleting a Story

We’ve figured out how to add a story, now let’s try deleting one. The first thing we’ll want to do is add a delete function. Go to your stories.js.jsx file and add a new function.

// stories.js.jsx
.
.
deleteRecord: function(story){
  var index = this.state.stories.indexOf(story);
  var records = React.addons.update(this.state.stories, { $splice: [[index, 1]] });
  this.setState({ stories: records });
},
.
.

Now, in our render function, we need to call deleteRecord. Where we are calling the Story class, add a new property.

.
.
{this.state.stories.map(function(story){
  return (
    <Story key={ story.id }
           story={ story }
           handleDeleteRecord={ self.deleteRecord } /> // adding this line
  )
})}
.
.

Now, we’ll need to go to our story.js.jsx file and create our Delete button.

// story.js.jsx
.
.
storyRow: function(){
  return (
    <div className="well">
      { this.props.story.body }
      <br />
      <br />
      <a className="btn btn-warning btn-xs"
        onClick={ this.handleUpvote }>That scared me</a>
      <span className="text-warning"> ({ this.state.upvotes })</span>
      <a className="btn btn-success btn-xs"
         onClick={ this.handleDownvote }>You Wimp!
      </a><span className="text-success"> ({ this.state.downvotes })</span>
      <a className="btn btn-link btn-xs"
         href={ this.state.storyLink }>Comments
      </a>
      <small><em>({ this.state.commentCount })</em></small>
      <a className="btn btn-danger btn-xs"  -------- add line staring here --------
         onClick={ this.handleDelete }>Delete
      </a> -------- and end here --------
    <span className="text-muted pull-right"><small>Created by { this.state.userName }</small></span>
      <br />
      <span className="text-muted pull-right"><small>Category: { this.state.categoryName }</small></span>
    </div>
  )
}

We are creating a “Delete” button that links to a handleDeletefunction. We’ll create that right above the render action.

// story.js.jsx
.
.
handleDelete: function(e){
  e.preventDefault();
  $.ajax({
    method: 'DELETE',
    url: '/stories/' + this.props.story.id,
    dataType: 'JSON',
    success: function(){
      this.props.handleDeleteRecord(this.props.story)
    }.bind(this)
  })
},
.
.

Here, we are use AJAX to delete a story. Upon successfully making the call, we are passing the story to our handleDeleteRecord property which will be calling the deleteRecord function on stories.js.jsx.

To test, make sure you’re logged in. When you click on the button, it should dynamically remove the story from the list and remove it from the database.

Conclusion of this Series

Using React.js in Rails is a very simple process. React.js itself is easy to learn since all you’re essentially doing is taking in JSON data and making AJAX calls to update the DOM. With the react-rails gem, integration is simple. You don’t have to rely on Flux, Webpack, Browserify, or any other technology to make React.js work with Rails. This app is far from a single page application. There are plenty of other things you can continue on with (updating stories, login/logout, top stories and random stories). With what you’ve learned thus far in this tutorial, you should be able to figure out how to make those features work. I hope you’ve enjoyed this two part series and begin building your next Rails app with React.js!

If you have any suggestions or know of a better method to do things than I’ve outlined here, let me know in the comments!

Add React.js to an Existing Rails Application Tutorial Part 1

Disclaimer: you should have some familiarity with Rails. If you can get a Rails app running from a .zip file or a git clone, you’ll be in good shape. You should also have read up a little on React.js. I won’t be covering what components/props/state are, just how to use them.

React.js is becoming the next flavor-of-the-month JavaScript framework. I’m not going to argue why you should/shouldn’t use React. There are plenty of resources out there that’ll give you the pros and cons. I’m assuming that if you’re here, you want to learn how to implement it in your existing Rails application. Or, maybe you’re starting a new application from scratch and want to use React for your frontend.

How is this tutorial different? It’s a more robust tutorial. We’re going to take this beyond a simple one-model application and actually implement React in an existing app. We won’t be using Babel, Browserify, Webpack, or Flux.

This is a complimentary tutorial to my ScareMe tutorial (an FMyLife clone). So first, you’ll want to download the project and get it up and running. The application is using Ruby 2.2.3 and Rails 4.2.1. You can download the .zip file and run the application or, for bonus points, you can follow the ScareMe tutorial and come back here to continue!

Build the ScareMe application

https://www.youtube.com/watch?v=AfzdghS5x38&list=PLTbnKfQpr5ZnaHN-Y_zoBAp-YW-jW4EnQ

Add React via react-rails gem

Once you have the app set up, the first thing you’ll want to do is go to your gemfile.rb and add the react-rails gem.

gem "react-rails"

Run bundle install. Following the steps on the Github page, you’ll want to run rails g react:install.

Next, go to application.rb and add config.react.addons = true. This will include React’s addon utilities, basically giving us more functions to work with.

First Component

Let’s start where our stories are. We can see this is being rendered by our stories/index.html.erb file. Before we change anything, we want to make sure we’re rendering JSON values in the controller. Go to the index action in stories_controller.rb. We’ll want to create another variable that gets all the Categories (you’ll see where we use it later) and make sure this renders JSON.

#stories_controller.rb
def index
  @stories = Story.all.order(id: :desc).page(params[:page]).per(10)
  @categories = Category.all
  respond_to do |format|
    format.html
    format.json { render json: @stories.to_json }
  end
end

Going back to stories/index.html.erb, we can replace the code with our React component. The file should look like this:

<%= react_component 'Stories', { stories: @stories, categories: @categories } %>
<div class="container">
  <%= paginate @stories %>
</div>

The ‘stories’ variable is being set to @stories and ‘categories’ to @categories. Both are passed in from stories_controller.rb

Now, we’ll need to create a stories.js.jsx file in app/assets/javascripts/components. This is going to be the component that renders all stories.

First, we need our getInitialState function. As the name implies, this sets the initial stories that we’ll see when we first land on this page. We’re setting the ‘stories’ variable to the ‘stories’ property that was passed in from the index.html.erb file and doing the same with categories.

//stories.js.jsx
var Stories = React.createClass({
  getInitialState: function(){
    return {
      stories: this.props.stories,
      categories: this.props.categories
    }
  }
})

Every component needs a render function, so let’s create that. We’re going to be using JSX to render our HTML. Before we build out this function, let’s take a look at our _stories_all.html.erb partial. Let’s copy/paste everything in the second container div into the render function of our stories.js.jsx file. However, we need to convert this to JSX and also need to get rid of the Ruby code since React won’t understand what it is. We’ll add things back in later.

To render all our stories and categories, we’ll want to iterate through each of the variables we created in the getInitialState function. Here’s what we’ll need to add to our render function.

//stories.js.jsx
var Stories = React.createClass({
  getInitialState: function(){
    return {
      stories: this.props.stories,
      categories: this.props.categories
    }
  },
 
  render: function(){
    var self = this;
    return (
      <div className="container">
        <div className="row">
          <div className="col-md-8 col-sm-12">
            { this.state.stories.map(function(story){
              return (
                <Story key={ story.id } 
                       story={ story } />
              )
            })}
          </div>
          <div className="col-md-4 col-sm-12">
            <div className="panel panel-default">
              <div className="panel-heading text-center">Categories</div>
              <ul className="list-group">
                { this.state.categories.map(function(category){
                  return (
                    <Category key={ category.id } 
                           category={ category } />
                  )
                })}
              </ul>
            </div>
          </div>
        </div>
      </div>
    )
  }
})

The code is equivalent to Ruby’s <%= @stories.each do |story| %>. Pay attention to what we’re returning. The “Story” is pointing it to a component with that name, which we’ll create shortly. We’re giving it two properties: key and story. Read more about keys here. As for the story, we’re setting it to the value of this story. Same for Category.

Category Component

We’re going to start with the Category component because it’s straight forward. Create category.js.jsx in app/assets/components.

var Category = React.createClass({
  getInitialState: function(){
    return {
      name: ''
    }
  },
 
  render: function(){
    return (
      <li className="list-group-item">
        <a>{ this.props.category.name }</a>
      </li>
    )
  }
})

We’re just returning the name of all the categories.

Story Component (this is where things get deep into React)

Create astory.js.jsx file in app/assets/javascripts/components. As with any component, we’ll need a getInitialState.

// story.js.jsx
var Story = React.createClass({
  getInitialState: function(){
    return {
      upvotes: this.props.story.cached_votes_up,
      downvotes: this.props.story.cached_votes_down
    }
  }
})

We’re setting the upvote/downvote variables to what they’re at currently. These will come in handy later.

Now, for the render function. Let’s go back into our _stories_all.html.erb partial. Look at where the stories are being rendered in the .each loop. We’ll want to take the code in the loop and place it in our render function, remembering to properly convert it to JSX and taking out the unnecessary markup.

// story.js.jsx
var Story = React.createClass({
  getInitialState: function(){
    return {
      upvotes: this.props.story.cached_votes_up,
      downvotes: this.props.story.cached_votes_down
    }
  },
 
  render: function(){
    return (
      <div class="well">
        { this.props.story.body }
        <br />
        <br />
        <a className="btn btn-warning btn-xs">That scared me!</a>
        <span className="text-warning"> ({ this.state.upvotes })</span>
        <a className="btn btn-success btn-xs">You wimp!</a>
        <span className="text-success"> ({ this.state.downvotes })</span>
        <a className="btn btn-link btn-xs">Comments</a>
        <small><em> (123)</em></small>
        <br />
        <span className="text-muted pull-right"><small>Created by: John Doe</small></span>
        <br />
        <span className="text-muted pull-right"><small>Category: Ghosts</small></span>
      </div>
    )
  }
})

Notice we’re using React to render our body, upvotes, and downvotes.

This is where we get deep into React. We need to finish out this render function. Let’s start with the easy stuff. We see ‘created by’, ‘category’, and ‘comments’. We’ll need to get the user’s name, category of the story, and how many comments it has. In normal Rails, we’d just do something like <%= story.user.name %> and be good to go. But because we don’t have access to ActiveRecord in these components, we’ll need to fetch the data by making an AJAX request. First, we need to set variables for the state of this component. Do this in the getInitialState function.

//story.js.jsx
.
.
getInitialState: function() {
  return {
    storyLink: '/stories/' + this.props.story.id,
    upvotes: this.props.story.cached_votes_up,
    downvotes: this.props.story.cached_votes_down,
    categoryName: '',
    userName: '',
    commentCount: ''
  };
},
.
.

We’re going to start with getting the categoryName. We need to build JSON data that gives us the category. We’ll need to create an endpoint, which is really just a controller action that renders JSON. Go into our routes.rb file and add a way for us to get the category.

#config/routes.rb
.
.
resources :stories do
  resources :comments
  member do
    put :like,     to: "stories#upvote"
    put :dislike,  to: "stories#downvote"
    get :category, to: "categories#story_category" #we're adding this line here
  end
  collection do
    get :search
  end
end
.
.

Next, go to categories_controller.rb and create a method for our newly created route.

# categories_controller.rb
def story_category
  @story = Story.find(params[:id])
  respond_to do |format|
    format.json { render json: @story.category }
  end
end

We are telling this to return a JSON value by finding the story and getting its category. Go back to our story.js.jsx file. React provides a function that allows us to change the state called componentDidMount. This essentially gets called when the component is rendered. We can create the componentDidMount function right underneath the getInitialState function.

.
.
componentDidMount: function() {
  $.getJSON('/stories/' + this.props.story.id + '/category.json', function(storyCategoryData) {
    if (this.isMounted()) {
      this.setState({
        categoryName: storyCategoryData.name
      })
    }
  }.bind(this));
},
.
.

What we’re essentially doing is making an AJAX GET request to the new endpoint we just created (when we coded the story_category action and new route). If we look at this code, we can see ‘setState’. This allows us to change the state of this component, changing the value of the categoryName variable we created in the getInitialState function.

Easily enough, we can do the same for getting the user info. Make changes to the following files (you’ll have to create a users_controller.rb):

#config/routes.rb
.
.
resources :stories do
  resources :comments
  member do
    put :like,     to: "stories#upvote"
    put :dislike,  to: "stories#downvote"
    get :user,     to: "users#story_user" #we're adding this line here
    get :category, to: "categories#story_category"
  end
  collection do
    get :search
  end
end
.
.
# controllers/users_controller.rb
class UsersController < ApplicationController
 
  def story_user
    @story = Story.find(params[:id])
    respond_to do |format|
      format.html
      format.json { render json: @story.user }
    end
  end
end
// story.js.jsx
.
.
componentDidMount: function() {
  $.getJSON('/stories/' + this.props.story.id + '/category.json', function(storyCategoryData) {
    if (this.isMounted()) {
      this.setState({
        categoryName: storyCategoryData.name
      })
    }
  }.bind(this));
 
 // adding this
  $.getJSON('/stories/' + this.props.story.id + '/user.json', function(storyUserData) {
    if (this.isMounted()) {
      this.setState({
        userName: storyUserData.name
      })
    }
  }.bind(this));
  // to our function
},
.
.

Getting the number of comments is just slightly different. Since we already have an action that’ll give us all the data we need, our endpoint has already been created. We’ll just need to create the index action and have it render JSON and get the length in our function. Also note, we’re using the Devise gem to handle authorization. We need to allow everyone access to this action, so we’ll have to edit the before_action :authenticate_user! callback.

# comments_controller.rb
before_action :authenticate_user!, except: :index
 
def index
  @comments = Comment.where(story_id: params[:story_id])
  respond_to do |format|
    format.html
    format.json { render json: @comments }
  end
end
// story.js.jsx
.
.
componentDidMount: function() {
   $.getJSON('/stories/' + this.props.story.id + '/category.json', function(storyCategoryData) {
    if (this.isMounted()) {
      this.setState({
        categoryName: storyCategoryData.name
      })
    }
  }.bind(this));
 
  $.getJSON('/stories/' + this.props.story.id + '/user.json', function(storyUserData) {
    if (this.isMounted()) {
      this.setState({
        userName: storyUserData.name
      })
    }
  }.bind(this));
 
  // adding this section
  $.getJSON('/stories/' + this.props.story.id + '/comments.json', function(commentData) {
    if (this.isMounted()) {
      this.setState({
        commentCount: commentData.length
      })
    }
  }.bind(this));
  // right here
},
.
.

Now that we’re fetching all the data we need for our stories, go back into the render function and set the data.

// story.js.jsx
.
.
render: function(){
  return (
    <div class="well">
      { this.props.story.body }
      <br />
      <br />
      <a className="btn btn-warning btn-xs">That scared me!</a>
      <span className="text-warning"> ({ this.state.upvotes })</span>
      <a className="btn btn-success btn-xs">You wimp!</a>
      <span className="text-success"> ({ this.state.downvotes })</span>
      <a className="btn btn-link btn-xs">Comments</a>
      <small><em> ({ this.state.commentCount })</em></small>
      <br />
      <span className="text-muted pull-right"><small>Created by: { this.state.userName }</small></span>
      <br />
      <span className="text-muted pull-right"><small>Category: { this.state.categoryName }</small></span>
    </div>
  )
}
.
.

The upvote/downvote buttons are next. These are different in that we’re not fetching data. We need to update the story when these buttons are clicked and we want to do it dynamically. Go to our stories_controller.rb file and find the upvote/downvote actions. Change it so it renders JSON.

# stories_controller.rb
def upvote
  @story.upvote_by(current_user)
  render json: @story
end
 
def downvote
  @story.downvote_by(current_user)
  render json: @story
end

We’ll need to create functions to handle the clicking of the upvote/downvote buttons. Taking a look at our routes, we’ll see we already have a like/dislike path. We’ll use those as our endpoints for our AJAX call. Put these two functions below the componentDidMount function.

// story.js.jsx
.
.
handleUpvote: function(e){
  e.preventDefault();
  $.ajax({
    method: 'PUT',
    url: '/stories/' + this.props.story.id + '/like',
    success: function(e){
      this.setState({
        upvotes: e.cached_votes_up,
        downvotes: e.cached_votes_down
      })
    }.bind(this)
  })
},
 
handleDownvote: function(e){
  e.preventDefault();
  $.ajax({
    method: 'PUT',
    url: '/stories/' + this.props.story.id + '/dislike',
    success: function(e){
      this.setState({
        downvotes: e.cached_votes_down,
        upvotes: e.cached_votes_up
      })
    }.bind(this)
  })
},
.
.

Notice how we’re calling setState to set the state to the new cached votes. This is basically updating the columns with the new values.

Going back to our render function. When someone clicks on our buttons, we want it to call these functions.

render: function(){
  return (
    <div className="well">
      { this.props.story.body }
      <br />
      <br />
      <a className="btn btn-warning btn-xs"
         onClick={ this.handleUpvote }>That scared me</a>
      <span className="text-warning"> ({ this.state.upvotes })</span>
      <a className="btn btn-success btn-xs"
         onClick={ this.handleDownvote }>You Wimp!</a>
     <span className="text-success"> ({ this.state.downvotes })</span>
      <a className="btn btn-link btn-xs"
         href={ this.state.storyLink }>Comments
      </a>
      <small><em>({ this.state.commentCount })</em></small>
      <span className="text-muted pull-right"><small>Created by { this.state.userName }</small></span>
      <br />
      <span className="text-muted pull-right"><small>Category: { this.state.categoryName }</small></span>
    </div>
  )
}

Let’s take a look at our application now. We’ve made a lot of changes and now things should be more dynamic. Data is being pulled when this page is rendered and when you click on the upvote/downvote buttons, things change in real-time (just remember, we’re only allowing users to vote. You’ll have to sign in for the button to work).

Conclusion of Part 1

We have now made our application more dynamic. This just gives you a taste of how powerful React is and how it makes real-time applications easy to build. Unlike other frameworks (*cough* Angular *cough*), React is relatively easy to pick up, even with minimal JavaScript knowledge. It’s essentially just making requests to get JSON values and updating the page based on events (like clicking a button). If you’d like to continue making this app more dynamic, follow along in Part 2 of the series. We’ll go further in making this application a more dynamic, single page application by creating more stories, deleting them, and filtering based on category.

Form_For Deeply Nested Resource

Sorry folks, haven’t posted in a while. Too busy with the day gig and discovering new technologies (looking at you Elixir/Phoenix).

So, one of my side projects had me creating a deeply nested resource. Essentially:

resources :market do
  resources :stands do
    resources :items
  end
end

It was hard trying to figure out how to be on the stands/show.html.erb and have a form_for @items. Here’s how I got it to work:

#stands_controller.rb
def show
  @market = Market.find(params[:market_id])
  @stand = @market.stands.find(params[:id])
end
#stands/show.html.erb
<%= form_for Item.new, url: market_stand_items_path(@market, @stand) do |f| %>
<% end %>

Hope that helps someone out there!

Git Git Git!!!

Everyone says Git is a revolutionary tool to manager your repository. Almost all modern development teams use Git…so it should be easy, right? For me, it’s been nothing but confusion. Yes, if you’re working alone and have your own project, it’s easy. Just do a git add, git commit, and git push straight to master and you’re perfectly fine. However, if you’re on a team, it gets confusing real fast.

People work on their own branches, push to your branch, merge branches together, merge into master, make schema changes, etc., etc. etc. It can get complicated really fast. I come from a GUI repository system (Eclipse with AccuRev). Everything was simple. If there were conflicts, you’d be given a nice comparison view. Pulling everyone else’s code was a simple button click. There was no concept of branches. You just keep pulling from the master branch and you’re all set. No on else can push to yours.

There are hundreds of git commands. Now, there are GUI programs that’ll do all the git magic for you, but I hesitate to use them because every team I’ve seen simply type the commands in the terminal. Will it make me less of a developer? Will I be able to speak everyone’s lingo? Are those tools crutches? These are questions that linger over me when I consider using a GUI git program. So, I keep on my path and continue using git in terminal. The reason I’m writing this post? I spent hours on one stupid step I didn’t know I should have taken…but makes sense now that I know.

I only work on my own branch of the repo. When I push, I push to my branch. When I pull, I pull to my branch. I’m hardly on master. That’s for my boss to manager and merge code in to. So, the last time I touched the master branch was 5 months ago. But, I ran into a bug and was wondering if it was my code that was causing it. So, I stashed all my code and switched to master. I played around for hours trying to figure out why I wasn’t on the latest commit. I can see in Github that HEAD was different than mine locally. I switched branches, reverted all my changes, did everything I could do…until I finally asked someone for help. The solution: I needed to do a “`git pull origin master“` even though I was already on master. I, for some reason, magically thought that once I switched to the master branch, I’d have all the latest changes. What I needed to do was pull all the code so I can have it locally…

So, just a heads-up to you all. If you want to have the latest code in the repo, your first step is to do a git pull. In hindsight, I feel like an idiot. Asking that question made it feel like I was brought all the way back to day one. Don’t let it happen you to!

Web Developers Need to Know JavaScript

or at the very least, jQuery. The web is a fast moving target and is constantly being pushed forward. Most websites have some type of dynamic component about them: shopping cart, blog feeds, content that magically appear/reappear when you click on a link. What makes all that happen? JavaScript.

Rails developers are notorious for their hatred of JavaScript. That’s how sub-languages like CoffeeScript emerge. With Ruby, we’re very spoiled. Semicolons, curly brackets, and function names are either nonexistent or minimal. A lot of new developers turn to Ruby as their first programming language, so seeing something like JavaScript is terrifying. As much as we all hate it, you will undoubtedly need to know it. And guess what? It’s actually not that bad.

jQuery is an amazing library. Chances are, the app you’re going to be working on is using jQuery in some form. It gets rid of all the clutter that is JavaScript. It has a steeper learning curve than Ruby, at least at first. But once you can get through the brackets and semicolons, it actually starts to make a lot of sense. The structure of the language will begin to seem logical and, dare I say, you will begin to like having all the parenthesis’ and curly brackets. I’ve even gotten to the point where my Rails apps will have the optional parenthesis’ for method parameters. When I pass in an argument? It’s in the parenthesis.

This is going to be controversial, especially coming from a Rails developer, but avoid CoffeeScript at all costs. It does some things well, but white-spaced languages are evil (looking at you too, Haml). Once you play around with jQuery for a few weeks, it’ll come together. You will enjoy being able to bring dynamicism to your application, even if it is just manipulating the DOM. I consider it more of a procedural type of language. It can be a pain trying to cover every single thing that needs to happen when you’re calling a “`click“` event, but once you figure it out, it’s amazing to see the magic happen in the browser.

Moral of the story:

  • Learn JavaScript/jQuery. You’re not a (full stack) web developer if you don’t know it.
  • Avoid CoffeeScript. Dumbing languages down is not the answer. And, do you really want to go through another preprocessor?
  • Stick with it. It’s intimidating at first and takes a little longer to learn, but once you know it, you’ll see the light at the end of the tunnel.

Not Everyone Has to Know How to Code

In the past few days, I’ve had the privilege of teaching others what I’ve learned so far in Ruby on Rails. I’ve given some folks my Craigslist Clone course for free to get a peer review of what people think. Some are good…some were bad. Constructive criticism is fantastic and welcomed. However, after hearing some complaints, I’m now starting to really believe what I’ve heard from many others: some people are not meant to be developers/programmers.

One of the criticisms I received was that I didn’t explain how I pulled up the search bar when I searched for files. Part of being a developer is learning how to learn. Conducting research is an enormous part of development/engineering/programming. Most folks would simply open up Google and conduct a 2 minute search on how to use their chosen text editor. I was literally told that I shouldn’t expect people to be masters of “Google-fu.”

Another one was that I wasn’t going over what a database schema was or how it all relates to the application. Some folks were looking for Computer Science 101, which can’t be covered in a 4 hour course on how to build an application. I think some people have the misconception that they’re going to receive the equivalent of a semester’s worth of a computer science class, which just isn’t the case. Most developers, especially Ruby/Rails developers, taught themselves how to code.

Learning how to program is a long, treacherous uphill battle that can never be won. Some of us just aren’t prepared to go through that journey, nor will we enjoy it. Some of us are. If you’ve decided that you want to teach yourself how to code, be prepared. You will experience frustration, loss of hope, and the will to continue. However, for those of us who are able to push through those experiences, there is a light at the end of the tunnel. The euphoria of getting something to work or finally fixing that bug makes it all worth it. It takes a special person to want to go through that process over and over and over again.

So, you have to ask yourself, are you really sure you want to learn how to code?

REST API is Not Simple…

If you’re working as a professional developer, you’ll more than likely be (at the very least) consuming an API. With everything turning to the web, having an API to let outside applications interact with yours (or vice versa) has become a very hot trend. One concept that is really taking the lead is RESTful APIs. I won’t get into the details, but essentially it provides a URL that can be called to do certain things in an application.

Conceptually, it’s easy. A web app like Twitter has an API that you can you use to post your tweets without ever having to log into Twitter. You just need your credentials (ex: username/password), get a few extra things to send along with your request, and you’re good! Well…not really. In practice, it’s a huge pain in the *ss.

There are a million different ways people implement APIs for their applications, so no one application is the same. Also, a simple username/password may not be enough. Sometimes you’ll have to go to the “developer” page of the application. Sometimes that page requires you to sign up (and if the username you use for the regular application is already taken…well, you’ll need to set up a new one). Sometimes, you’ll need 2..5 different “tokens.” Oh, guess what? Those tokens are only valid for 20 days, so you’ll have to generate a new one by logging in to the application again which kind of defeats the purpose of the API.

So if everyone is implementing an API for their applications, why can it be so hard? I have a theory…one that comes directly from my own experience. It really boils down to one person: the developer. They’re the ones building it, and, you guessed it, they’re the ones documenting it. I hate to admit it, but as a developer, I love building things. What’s the thing I hate most? Documenting them.

I think there in lies the problem with APIs. Not so much the technical capabilities, but the documentation that goes along with it. Unless you’re told what to do with the API, you have no idea how to actually use it. The biggest, most well respected companies in the world have some of the worst documentation for their applications. Even if they do, it’s extremely hard to find. And who’s the one to blame? The developer :).

My recommendation to all the development teams out there: hire a documentation specialist!

Heroku: Missing secret_token and secret_key_base for ‘production’

If you’ve been following good conventions when pushing your Rails application out to Heroku, you’ll know that you’re not supposed to push your secrets.yml file to your repo. As such, when you push your code to Heroku, the file won’t be there either. Heroku will try looking for this file, and when it doesn’t find it, it throws this error message:

“Missing secret_token and secret_key_base for ‘production’ environment, set these values in config/secrets.yml”

After spending hours online figuring out how to fix this, there was only one easy answer. You could rely on a few gems out there (Figaro being the biggest one), but you know my philosophy: be a minimalist when you can.

Don’t worry about the secret_token. I think the newer Rails versions deprecated the secret_token.rb file, so you won’t find that if your Rails app is new. To fix the issue, simply add this one line to your production.rb file:

config.secret_key_base = ENV[“SECRET_KEY_BASE”]

This will automagically create a token and assign it to your secret_key_base. Push to Heroku and you’re all set.

Easy as pie.

Best Cities for Ruby on Rails Jobs

Most of us learning how to program are doing it because we want a job. Now, if you’re looking to be an entrepreneur and are learning to program to start your own startup, I still think you should get a job first. I’ve said it before: there is no better way to learn how to code than by getting paid to learn from senior level developers. How do you do that? By landing a full-time gig.

I’ve been keeping an eye on the market to see what the Ruby on Rails job trends are. If you’re looking to become a junior level developer, your chances of getting a job are exponentially higher in a bigger market. It took me a year to get mine because I’m in the Twin Cities. A friend of a friend spent 3 months learning Rails when he landed his, and I’m absolutely convinced it’s because he’s based out of Los Angeles. After desperately looking for jobs for months before (thankfully) getting my current job, here are the cities that I’ve found to have the most Ruby on Rails positions.

**Disclaimer: this is strictly based on me scouring Indeed, Dice, and StackOverflow Careers and seeing the amount of jobs. I didn’t use any sort of advanced algorithm to come up with my findings.

  • San Fransico – Bay Area
    No surprise here. With a new startup seemingly being created every minute, a lot of them turn to Ruby on Rails. That’s how Twitter and a lot of other now-successful companies got started.
  • Los Angeles
    Another huge city in California. In a place full of celebrities and Hollywood wannabes, I’m surprised at the amount of tech jobs in Los Angeles. You don’t often hear about too many companies whose headquarters are here, but there definitely are a lot of job postings.
  • New York
    I love New York, especially the New York City area. I’ve only been there once, but if I was a billionaire (not millionaire, wouldn’t be able to afford it), I’d live here. In a world of stock traders and financial advisors, I am a little shocked that New York has one of the biggest markets for Ruby on Rails developers. I did a triple-take and thought about uprooting my family to move here when I was looking for a job. Thankfully, I found my current one and have a much lower cost of living.
  • Boston
    Facebook, anyone? Boston, along with most of that northeast region, has a strong tech scene. I think all the wannabe Mark Zuckerberg ivy league students are the culprits. There are a ton of startups trying to be the next #{insert startup here}. A lot of jobs out here, if you can handle the crazy amounts of snow they’ve been getting these past few winters.
  • Denver
    Two of the most highly regarded coding bootcamps reside here: Turing and Galvanize. It’s no secret that Denver has become a hotbed for technology, especially web development. We were also considering moving here as well. It has well balanced seasons, never gets too hot nor too cold, isn’t overpopulated, and has a progressive community. A lot of openings here go unfilled.
  • Washington D.C., North Carolina, Atlanta, Austin
    The rest here are in dire need of Rails developers. They’re at that sweet spot where there is an emerging tech market, but they don’t have the supply.

Which city is best depends on where you’re at in your career. If you’re looking to land a junior developer role, you’ll probably want to move to a bigger market like San Francisco or New York. Those places will have all the senior level talent and are more likely able to afford taking a risk on new learners. If you’ve got a few years under your belt and are at an intermediate level, a smaller market might benefit you more. There’s a ton of demand but not enough people to fill the positions. Someone with 3-4 years of experience will look like gold and you’ll definitely have your pickings on who to join. If you’re a senior level developer to knows how to architect an application, forget all of these locations! Find a job where you can work remote!

There you have it. My opinion on which locations have the most amount of Rails positions. If you’re in a small town where there isn’t a tech scene, moving might be a good option. Being around fellow developers and having a community will definitely give you an advantage as far as your learning and your job opporutnities.