In this post, I’m going to break down how I created my rails app.

  1. First and foremost, you need to really breakdown your app, how you want it look like, what do you want your users experience to be. I decided to go with the wineries of California since I live in the area. My users could post a winery that they visited, and other users could comment on these wineries. Also the wineries are associated to a region that they belong to. I think it could be a great way to discover new wineries.
  2. Using the resource generator gives you even more to start with — running magically (not actually magically) creates:
1) a migration in db/migrate/20190714193807_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
t.string :name
t.string :username
t.string :emailt.timestamps
end
end
end
2) the User model in app/models/user.rb
class User < ApplicationRecord
end
3) a User controller in app/controllers/users_controller.rb
class UsersController < ApplicationController
end
4) opens up all of the routes in config/routes.rbRails.application.routes.draw do
resources :users
end
Top-tip: add '--no-test-framework' in order not to create tests.
  1. Thinking about your models and their relationships is really important. I decided to go as followed:
  • Model Winery
- belongs_to :user
- belongs_to :region
- has_many :comments
- has_many :users, through: :comments
  • Model User
- has_many :wineries
- has_many :comments
- has_many :commented_wineries, through: :comments, source: :winery
- has_many :regions, through: :wineries
- has_secure_password
  • Model Comment
- belongs_to :user
- belongs_to :winery
  • Model Region
- has_many :wineries

4. Once all your models are defined, and that your migrations are up to date, you can test it out in your rails console by create a new winery for example and make sure it is associated with a user.

Top-tip: You can type ‘rails c -s’ if you do not want to create data that will stay.

5. Also an important step is to set up your validations in your models. For example:

  • Model User
...
validates :name, presence: true, uniqueness: true
validates :email, presence: true

6. Your routes need to be set in your config>routes.rb. I decided to go for 3 nested routes as so:

resources :wineries do
resources :comments, only: [:new, :create, :index]
end
resources :comments
resources :users do
resources :wineries, only: [:new, :create, :index]
end
resources :regions do
resources :wineries, only: [:new, :create, :index, :show]
end

7. Your controllers will follow a pattern like followed:

class WineriesController < ApplicationControllerdef new
@winery = Winery.new
end
def create
@winery = Winery.new(winery_params)
if @winery.save
redirect_to wineries_path(@region)
else
render :new
end
end
def index
@wineries = Winery.all
end
def show
@winery = Winery.find_by(id: params[:id])
end
def edit
@winery = Winery.find_by(id: params[:id])
end
def update
@winery = Winery.find_by(id: params[:id])
if @winery.update(winery_params)
redirect_to winery_path(@winery)
else
render :edit
end
end
def destroy
@winery.destroy
flash[:notice] = "#{@winery.name} was deleted"
redirect_to wineries_path
end
privatedef winery_params
params.require(:winery).permit(:name, :website, :phone, :description, :region_id, region_attributes: [:name])
end

Note that they will need to be modified depending of your associations. Also you can DRY up your code by using rails helper methods like so:

class WineriesController < ApplicationController
before_action :find_winery, only: [:show, :edit, :update, :destroy]
...private
def find_winery
@winery = Winery.find_by(id: params[:id])
end

8. In your view templates, Rails provides form helpers that gives us a shortcuts to make our lives as developers a tad easier.

  • form_tag: This generates an HTML form for us and lets you specify options you want for your form.

Example of form_tag :

<%= form_tag url_for(action: ‘create’), method: “post” do %>
<%= label_tag ‘Title’ %>
<%= text_field_tag ‘title’, @post.title %>
<%= label_tag ‘Body’ %>
<%= text_area_tag ‘body’, @post.body %>
<%= label_tag ‘Author’ %>
<%= text_field_tag ‘author’, @post.author %>
<%= submit_tag “Create Post” %>
<% end %>
  • form_for: form_for method follows RESTful conventions on its own. It accepts the instance of the model as an argument where it makes assumptions for you (which is why it can be seen to be preferred over form_tag). form_for prefers the argument that you’re passing in to be an active record object. This will easily make a create or edit form.

Example of form_for :

<%= form_for @winery do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>

<%= f.submit %>
<% end %>

We use form_for with a specific model and use form_tag when you don’t have a model for it.

9. Partials: Rails allows us to create some partials in order to keep our codes DRY. The best example is in the view template, for example my wineries/new and /edit forms. Both will be similar so I created a partial wineries/_form.

<%= form_for winery do |f| %>
...
<%= f.submit class: 'red darken-3 btn btn-default' %>
<% end %>

And in my new and edit:

<%= render partial: "form", locals: { winery: @winery } %>

Conclusion:

What I wish I had done was take more time to define my models and associations. This is the most important part of the project. I didn’t have a clearly idea of what my final result should look like so I struggled with my relations and got lost at some point where I had to start my project from scratch. Planning for this project is key!

French guy who recently moved to the United States. I am also changing career after having worked 13 years in restaurants. I will be going into coding.