FlatCoin on Rails
Published: 2021-04-30 15:05:50

This App was develop as a Flatiron School Rails project. I developed this app to help users practice building cryptocurrency portfolios and react to the markets in real time safely using fake money.

> **Note:** This is a continuation of my previous Sinatra project, click the following link to find useful information about the API I'm using and more details [FlatCoin](https://dev.to/drivera53/flatcoin-nil).

# Rails New App Setup:
```ruby
rails new Project_name
```
Then, type:
```ruby
rails s
```
And go to http://127.0.0.1:3000 OMG! Yes, that's it. you're on Rails!
Next thing you want to start creating the resources needed:
```ruby
rails g resource User name:string password:password_digest email:string uid:string provider:string --no-test-framework 
``` 
```ruby
rails g resource Portfolio name:string description:text current_balance:integer initial_balance:integer user_id:integer --no-test-framework 
```
```ruby
rails g resource Comment user_id:integer portfolio_id:integer content:text --no-test-framework 
```
```ruby
rails g resource Trade coin_name:string coin_id:string price:decimal quantity:integer user_id:integer portfolio_id:integer --no-test-framework 
```
By running the above, Rails will generate the migrations, models, controllers, routes an even the views folders for you. Thanks Rails!
Now it's the time to run a migration:
```ruby
rails db:migrate 
```
Next step associations and validations:
```ruby
class User < ApplicationRecord
  has_secure_password

  # Remane relationship to group another name
  has_many :created_portfolios, foreign_key: "user_id", class_name: "Portfolio"
  has_many :trades, through: :created_portfolios

  has_many :comments
  has_many :portfolios, through: :comments

  validates :name, presence: true
  validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }, uniqueness: true
end 
```
```ruby
class Portfolio < ApplicationRecord
    belongs_to :user
    
    has_many :comments
    has_many :users, through: :comments

    has_many :trades

    validates :name, presence: true
    validates :description, presence: true
    validates :initial_balance, presence: true, numericality: { only_integer: true }

    # You must include at least one class level ActiveRecord scope method
    scope :search, -> (query) { self.where("name LIKE ?", "%#{query}%") }

    # def self.most_recent
    #     self.order(created_at: :asc)
    # end
    scope :most_recent, -> { self.order(created_at: :desc) }

    def max_coins(price)
        (self.current_balance / price).to_i
    end
end 
```
```ruby
class Trade < ApplicationRecord
    belongs_to :user
    belongs_to :portfolio

    validates :quantity, presence: true, numericality: { only_integer: true }
end 
```
```ruby
class Comment < ApplicationRecord
    belongs_to :user
    belongs_to :portfolio

    validates :content, presence: true
end 
```
Routes:
```ruby
Rails.application.routes.draw do
  
  root 'static#home'
  match '/auth/:provider/callback', to: 'sessions#github_omniauth', via: [:get, :post]
  #resources :users
  get '/signup', to: 'users#new'
  post '/signup', to: 'users#create'

  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'

  get '/search', to: 'portfolios#search', as: 'search'

  delete '/logout', to: "sessions#logout"

  get '/my_portfolios', to: 'portfolios#my_portfolios', as: 'my_portfolios'

  resources :portfolios do
    resources :comments, only: [:create]
    resources :trades, only: [:create, :show, :destroy]
    get '/trades/new', to: 'portfolios#my_portfolios'
    post '/trades/new', to: 'trades#create_portfolio_trade', as: 'create_portfolio_trade'
  end
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end 
```
From here on the logic is very similar to my previous Sinatra project [FlatCoin](https://dev.to/drivera53/flatcoin-nil), rails give us an easy way to create forms, such as the following:
```ruby
<%= form_with(model: [@portfolio, @trade]) do |f| %>
    <%= f.hidden_field :user_id, value: current_user.id %>
    <%= f.hidden_field :portfolio_id, value: @portfolio.id %>
    <%= f.hidden_field :coin_name, value: @coin.name %>
    <%= f.hidden_field :coin_id, value: @coin_id %>
    <%= f.hidden_field :price, value: @coin.current_price %>
    <%= f.label :quantity %>
    <%= f.text_field :quantity %>
    <%= f.submit :trade, value: 'Buy NOW!' %>
<% end %>
``` 
# Setting up the GitHub authentication:
- Visit https://github.com/settings/developers
- Click "New OAuth App"
- Give it a name, Homepage URL: http://127.0.0.1:3000 (Or any other path that Rails is listening on), Description, Authorization call back URL: http://127.0.0.1:3000/auth/github/callback
- Click "Register application"
- Create a `.env` file in main directory and add your GitHub keys.
```ruby
GITHUB_KEY=33...
GITHUB_SECRET=519... 
```
- If you run into issues, check the following documentation [OmniAuth: Standardized Multi-Provider Authentication](https://github.com/omniauth/omniauth#integrating-omniauth-into-your-application)

Struggling with Sinatra gave me the knowledge and appreciation to Rails.   
Check out a quick [YouTube](https://www.youtube.com/watch?v=e8Jn45GQUgM) video of my project.
Check out the project here on [GitHub](https://github.com/drivera53/flatcoin_on_rails)!