fabiochiu/medium-articles huggingface dataset:
Rails-TDD
Tags: Rails, Rspec

TDD(Test-Driven Development) 測試驅動開發

測試就是一段程式碼去驗證另一段程式碼，寫測試目的是為了確保程式可以依照預期行為運作

ATM功能

存錢功能

- 可以存錢

- 不可以存0元或是小於0元的金額 領錢功能

- 可以領錢

- 不能領0元或是小於0元的金額

- 不能領超過本身餘額

起手式

RSpec.descrie ATM do

content "存錢功能" do (做分類)

it "可以存錢 do (測試進入點)

end

end

end 此時不會有一個叫做ATM的東西，記得要做給他

保持3A原則

A = Arrange

A = Act

A = Assert 排好 -> 搓搓看 -> 結果

發生狀況順序1

class ATM

end //A = Arrange

atm = ATM.new(10)

//A = Act

atm.deposit(5)

//A = Assert

expect(atm.balance).to be 15 此時會發生一個錯誤

就是ATM.new(10)，這裡帶了一個參數，但是沒人來接他 在ATM的上層Object裡面雖然有一個私有方法叫做"initialize"，但是他預設是沒帶參數的，因此我們現在把他叫出來讓他帶上參數 意思也就是說，所有被new出來的實體，就會有initialize這個方法 |

V class ATM

def initialize(amount)

end

end 這樣就會把參數帶進來了！！

發生狀況順序2

這時候發生了另個問題...

沒有deposit 這個方法...

因此我們就做給他！ class ATM

def initialize(amount)

end def deposit(add_money)

end

end 做完之後再跑一次RSpec之後想當然的，沒有balance方法，因此又噴錯了。

那我們就在做給它 class ATM

def initialize(amount)

end def deposit(add_money)

end def balance

15

end

end 好，他會動了，也不會出錯了。

但是這樣寫"正確答案的測試是絕對會出問題的"

隨著測試越來越多就會越縝密

因此這段我們之後一定會出錯，之後就要來修

待續…
Rails-物件導向
Tags: Rails

in In Bitcoin We Trust
Model Generator in Rails. Rails comes with a built-in script…
Tags: Software Development, Rails Generators, Model, Rails, Generator

Photo by Joshua Aragon on Unsplash

Rails comes with a built-in script called Generator. It can produce many rails items that are necessary in every web/mobile application such as Models, and Migration. In this blog I will be explaining the Model Generator, how to use it, and how to customize it.

Model Generator

Model generator is one of the most common generators in Rails. Here is the command for the simplest one:

rails generate model Test

This command will generate a model called Test “app/models/test.rb” that has no attributes/class variables. The model will look something like this:

class Test < ApplicationRecord end

It will also create an empty migration for the Test Model, so that when you run it, it will create the actual table for this model. The migration file “db/migrate/create_tests.rb” will look similar to this:

class CreateTests < ActiveRecord::Migration[6.0]

def change

create_table :tests do |t|



t.timestamps

end

end

end

Then inside the change method, you will have to add each of the table attributes and specify what data types they will be:
Alternative ways to include NULL values in the results while using SQL negation commands(!= or NOT IN) with Rails
By: Sampat Badhe
Tags: Rails, Sql, Sql Null Functions

In the previous article, we went through How NOT IN works with NULL values. We also learned how we can overcome this restriction. In this article, we will look at alternative ways to handle NULL values with SQL functions.

So basically when we use != or NOT IN in query, it ignores the records with NULL values for fields.

User.where("state != ?", 'active') SELECT * FROM users WHERE state != 'active'

OR

User.where("state NOT IN (?)", ['active']) SELECT * FROM users WHERE state NOT IN ('active')

The above queries will consider records with state having a NOT NULL value, but state having a NULL value will not be considered. To consider state with the NULL value, we have to explicitly add the OR clause.

User.where("state != ? OR state IS NULL", 'active') SELECT * FROM users WHERE state != 'active' OR state IS NULL

OR

User.where("state NOT IN (?) OR state IS NULL", ['active']) SELECT * FROM users WHERE state NOT IN ('active') OR state IS NULL

Lets take a look at the alternatives for handling NULL values

With COALESCE function — MySQL/SQL Server/SQLite/PostgreSQL/Oracle

The COALESCE function returns the first non- NULL expression in the specified list. If all the arguments are NULL , then it will return NULL COALESCE(expression, replacement1...n)

Here, considering '' (blank string) for NULL value while performing query to return records with NULL value.

User.where("COALESCE(state, '') != 'active'") With IFNULL function in MySQL/SQLite

The MySQL IFNULL function returns an alternative value if an expression is NULL .

IFNULL(expression, replacement)

User.where("IFNULL(state, '') != 'active'") With ISNULL function in SQL Server

The SQL Server ISNULL function returns an alternative value if an expression is NULL .

ISNULL(expression, replacement)

User.where("ISNULL(state, '') != 'active'") With NVL function in Oracle

The Oracle NVL function returns an alternative value if an expression is NULL .

NVL(expression, replacement)

User.where("NVL(state, '') != 'active'") With IS DISTINCT FROM statement in PostgreSQL

In PostgreSQL , we can use IS DISTINCT FROM to work around the problems of NULL , which treat NULL as a comparable value.

attribute IS DISTINCT FROM value

User.where("state IS DISTINCT FROM 'active'")

I hope you enjoyed this article and learned other ways of dealing with NULL values. Feel free to share your feedback or suggestion. We would ❤️ to hear from you. Thank you.

References
Use a License Monitor
By: Damien Burke
Tags: Rails, Licenses, Open Source, Gems

Use a License Monitor

Published: December 22, 2020

This is part of The Annotated Guide to a New Rails App, a list of recommendations to make developing your Rails app more productive and joyful.

In this article, we are talking about using a license monitor.

When

The longer you wait before adding a license monitor, the more work you will have to do to correct problems that have accumulated. For that reason, I recommend adding a license monitor early — and absolutely before you start distributing your application.

Why

Rails applications often leverage an extensive network of open source software distributed under a variety of licenses. It is very important to avoid using software if you do not agree with the terms of the license.

A license monitor can check the licenses of your libraries and make sure they only use licenses you agree to abide by.

How

Use License Finder.

Install

To install, add gem 'license_finder' to the development section of your Gemfile .

To run, use the command: license_finder .

Configure

For License Finder to work, it needs to know which licenses are acceptable to you. Use the permit subcommand to record those. Here is an example with what I think are reasonable defaults:

bundle exec license_finder permit add MIT MIT* ruby "Apache 2.0" ISC BSD \

"Simplified BSD" "New BSD" BSD-3-Clause 0BSD BSD* Unlicense CC0-1.0 CC-BY-3.0 \

CC-BY-4.0 WTFPL "Brakeman Public Use License"

Some packages list multiple licenses in a way that License Finder doesn’t understand. For those, we need to correct which licenses are available.

bundle exec license_finder licenses add amdefine MIT

bundle exec license_finder licenses add amdefine BSD-3-Clause



bundle exec license_finder licenses add atob MIT

bundle exec license_finder licenses add atob Apache-2.0



bundle exec license_finder licenses add node-forge BSD-3-Clause

bundle exec license_finder licenses add node-forge GPL-2.0



bundle exec license_finder licenses add pako MIT

bundle exec license_finder licenses add pako Zlib



bundle exec license_finder licenses add path-is-inside WTFPL

bundle exec license_finder licenses add path-is-inside MIT



bundle exec license_finder licenses add sha.js MIT

bundle exec license_finder licenses add sha.js BSD-3-Clause

Finally, if you followed the advice on library vulnerability checks then you installed bundler-audit. Bundler-audit is has a GPL license, which means we can’t incorporate it into non-GPL code. But it is not part of our app — it’s only a tool we use — so it’s okay.

bundle exec license_finder approvals add bundler-audit

Caveat

I am not a lawyer and neither is License Finder. None of this will guarantee that you do not illegally incorporate other people’s software into your code. Nor will it guarantee that you are not creating liabilities or obligations that you do not want.

If your need legal advise, consult with an attorney licensed to practice in your jurisdiction.
Anxiety on Rails.
By: Oumaima Azzat
Tags: Bootcamp, Anxiety, Stress And Anxiety, Coding, Rails

Im currently five weeks into my Software Engineering course at Flatiron School and lets just say the ambitious and hungry girl that I was five weeks ago has slowly started to go back into her shell. CAUTION: this blog is not meant to be gloomy or depressive, but more so a helping hand for anyone that feels like their anxiety has reached new heights during their bootcamp course.

I have come to learn that a lot of the emotions I am feeling and experiencing are apparently “normal”. Lets set the scene — you’re in a bootcamp where 1. Information is being thrown at you constantly at ground breaking speed 2. LABS (need I say more?) 3. Code challenges and the fear of not passing them (that deserves a whole blog on its own) and 4. Your incredibly talented and abled brain telling you you cant do it — cue the crippling anxiety.

No one said this was going to be easy, I certainly did not think it would be. But lets be honest…. holy **** this is hard. If you suffer from anxiety, a bootcamp will truthfully only heighten the “regular” anxiety that you experience. I should also highlight the fact that there is absolutley nothing shameful about experiencing anxiety. Once I became vulnerable to my cohort, the amount of love and support I recieved from my peers was astounding. I can guarantee you, you are not alone!! There is a high probability that there are other people in your course who feel the exact same way! So here is my guide to keeping anxiety low during these stressful times:
How Rails Generators Make CRUD Workflow Go Smoother
By: Noura Loudani
Tags: Rails, Beginner, Generator, Ruby on Rails

Photo by Michael Hodgson, New York 2019

Ruby on Rails or Rails is a user-friendly open source framework. Its main goal is to optimize the web application development process.

Rails developers must follow standard best practice conventions in order for the magic to happen. Rails is built on the principle of convention over configuration (for example: a model is singular — a controller is plural).

Generators are a nifty way of integrating standard features that help creating CRUD functionalities in an application. So instead of having to build them manually each time, Rails came out with a faster automated way. Let’s break this more down by running rails g in the command line of a rails application:

General options:

-h, [--help] # Print generator's options and usage

-p, [--pretend] # Run but do not make any changes

-f, [--force] # Overwrite files that already exist

-s, [--skip] # Skip files that already exist

-q, [--quiet] # Suppress status output Please choose a generator below. Rails:

application_record

assets

channel

controller

generator

helper

integration_test

jbuilder

job

mailbox

mailer

migration

model

resource

scaffold

scaffold_controller

system_test

task ActiveRecord:

active_record:application_record TestUnit:

test_unit:channel

test_unit:generator

test_unit:mailbox

test_unit:plugin

We see a list of all built-in generator, from application record to task . If we want to generate any of them, all we need is run rails g (name of generator we want to generate).

Let’s compare two of the most common commands. rails g resource vs rails g migration . I personally consider the first one to be the smartest of all. For example, running rails g resource SignUp username id_number:integer would mainly create the following:

A migration file with the proper name/path: /db/migrate/20201221141414_create_sign_ups.rb, as well as the corresponding attributes:

class CreateSignUps < ActiveRecord::Migration[6.0] def change create_table :sign_ups do |t| t.string :username t.integer :id_number t.timestamps end end end

A model file that inherits from ApplicationRecord

class SignUp < ApplicationRecord end

A controller file that inherits from ApplicationController

A view directory

A full resources call in the routes.rb file

On the other hand, for example, we can add a new table to a data base by running rails g migration <SignUp> . This create the migration file ‘’######_sign_up.rb

class SignUp < ActiveRecord::Migration[6.0] def change end end

Our take on this: Rails generators follow Rails best practices, which includes utilizing RESTful naming patterns.
Deploying a Rails/React App
Tags: Software Development, Heroku, Programming, Rails, React

Deploying a React Frontend to Netlify

In the script section of your package.json , in "build" , add “react-scripts build && echo ‘/* /index.html 200’ > ./build/_redirects” . This script ensures that if you had chose to use something for routing (for example, React Router), the app will serve index.html instead of giving a 404 error, no matter what route you might be accessing the app from. To read more on this, please visit the Netlify documentation.

...

"scripts": {

"start": "react-scripts start",

"build": "react-scripts build && echo '/* /index.html 200' > ./build/_redirects",

...

2. Create a Netlify account.

3. Under the Sites section, click “New site from Git”.

4. Select “Github”.

5. Select your project.

6. Select a branch of your project to deploy.

7. Set up environment variables to be available in Netlify. To do so, click “Site setting”, on the side bar, click “Build & deploy”, click “Environment”, then input variables according to what you have stored in your local .env file. This could be various sensitive API keys, for example. Next, add key CI and set the value to false as one of the environment variables.

8. Go to “Deploys”, click “Trigger deploy”, and select “Clear cache and deploy site”.

Congratulations! You should now be able to access your frontend via the link Netlify has provided.
把隊友的專案clone下來，為什麼沒辦法啟動Rails Server了？-應該是因為database換成PostgreSQL了吧
Tags: Rails

in In Bitcoin We Trust
太強啦！
Tags: 金流, 藍新, Rails

in In Bitcoin We Trust
rails好用的套件-devise(會員系統)
By: Mino Chen
Tags: Rails

Learn more. Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Make Medium yours. Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore
當專案跟本機的ruby版本不同時處理方式
By: Mino Chen
Tags: Rails

in In Bitcoin We Trust
Redux Thunk — When my Function it’s called?
By: Zaharia Anton
Tags: Redux Thunk, Redux, JavaScript, Rails, React

While I was in an interview about my Raffle project, I’ve got a very interesting question that made me research a little more about middlewares.

Raffle project was a Ruby on Rails API for backend and React JS for frontend app.

In one of my components, I had the following code:

A simple mapDispatchToProps function, that was helping me to dispatch the newPost action, which was a fetch request the backend to create a new record.

My interviewer asked me something that blocked me for a couple of minutes.

When the function newPost() it’s called?

I was a bit confused as it looks pretty obvious, as this function was a callback for an onClick event. So my first answer was:

“When the onClick event gets triggered.”

That was not the expected answer so we followed the Redux flow to see where the actual work it’s happening.

onClick event it’s triggered {this.props.newPost} , this callback comes from newPost: (post) => dispatch(newPost(post));

No work yet, as we are just dispatching a newPost action that I was talking earlier.

Without Thunk, the work will happen in the action but now, after the fetch, we are again dispatching something, this time, an object {type: "CREATE_POST", payload: result} .

So where the work happens, as we are always returning plain objects?

The answer is that Thunk executes the code for us, that is why it’s called a middleware, being the bridge between the app and Redux.

It was confusing then, but now after realising that my code is only passing pieces of code and not actually running it, it’s making sense.

I can only be very grateful to my interviewer as I could go deeper into this and learned something new.
Steel Trading Company in Mandi Gobindgarh
Tags: Channel, Flat Bars, Rails, Steel, Angles

About Us

Rohit Steel Trading Company in Mandi Gobindgarh is a leading Steel Trading Company in various products like Angles, Channels, Beams, Flat Bars, Sheets & Plates, Galvanised Coils/Sheets, Pipelines, Rails, Binding Wire and special steel products. Our company established in the year 1980 at Mandi Gobindgarh and another leap forward expanded to pan India to serve our customers with branches. We are the authorized Trader of steel Product (Angles, Channels, Beams, Flat Bars, Sheets & Plates, Galvanised Coils/Sheets, Pipelines, Rails, Binding Wire) for the entire Punjab state having a channel presence with more than 200 retailers. Our every stockyard is fully modernized with overhead cranes, adequate stocks to fulfill your needs along with highly experienced Technical manpower to cater to you uninterrupted and timely deliveries as well as we also offer after-sales services promptly to any of your queries or complaints.

We would appreciate your kind cooperation to allow us to prove our credibility by supplying you with the products according to your need at your existing and upcoming projects at a competitive price within the stipulated time frame. For standardization of our services and quality, our company is a certified company.

Vision

To be the leading company in India supplying the best quality steel and steel products and setting benchmarks in customer satisfaction.

Mision

To create value for customers by providing the best products, customized service, and strive for excellence without compromising on values or ethics.

Value

Setting high standards of business and transaction, practice the highest principles of work ethics, maintain transparency, and persistently strive for excellence.

https://www.instagram.com/rohitsteels/

https://twitter.com/rohit96043354
SimpleCov, your test coverage files attached to each PR with GithubActions
By: Mohamed Barakat
Tags: Rspec, Ruby, Github, Unit Testing, Rails

SimpleCov, your test coverage files attached to each PR with GithubActions Mohamed Barakat ·Dec 15, 2020

Something small, I wanted to share, nice I just discovered while playing around with( Github Actions) on a new side learning project!

it’s a workaround to have your test coverage files attached to each PR.

- I am using SimpleCov for code coverage in a rails project( as it’s free )

https://github.com/simplecov-ruby/simplecov

- using Upload-Artifact from GitHub actions allow you to upload files/folder!

https://github.com/actions/upload-artifact

include the coverage folder that runs on the CI(with the assets included)

in your CI.yml file

in your .gitignore file, please add!

.gitignore file

I am not a professional Medium writer, but just wanted to share 😄
Code Vulnerability Checks
By: Damien Burke
Tags: Rails, Brakeman, Security

Code Vulnerability Checks

Published: December 15, 2020

This is part of The Annotated Guide to a New Rails App, a list of recommendations to make developing your Rails app more productive and joyful.

In this article, we are talking about checking for code vulnerabilities.

When

You should check for code vulnerabilities before creating a production environment.

Why

As soon as you make your application available on the Internet, if there is a vulnerability in your code, it is possible that that vulnerability could be used to compromise your application.

How

Use Brakeman for code analysis to catch potential security vulnerabilities.

To install, add gem 'brakeman' to the development section of your Gemfile and run bundle .

To run use the command brakeman .

Fix any issues Brakeman finds.

Gotchas

Brakeman checks for a lot of common errors that create security vulnerabilities. Of course, it cannot catch all security issues. Be careful out there.
Magically create association in ‘has_many :through’ relationship in Rails
By: Robert Guiscard
Tags: Rails

You may know fields_for and accepts_nested_attributes_for already to input nested attributes. It is convenient but rather complicated way to create association between models. For a more simple situation where you have to add or remove association between two models in a has_many :through relationship, there is a magical way which may suit you.

Here is the relationships:

class Task < ApplicationRecord

has_many assignings, inverse_of: :task, dependent: :destroy

has_many assignees, through: :assignings, source: :contact

end class Contact < ApplicationRecord

has_many assignings, inverse_of: :contact, dependent: :destroy

end class Assigning < ApplicationRecord

belongs_to :contact, inverse_of: :assignings

belongs_to :task, inverse_of: :assignings

end

For any given task, it can have many assignees. I intentionally use Contact as model name to demonstrate the name convention in this case.

Now, in the task editing form, I would like to have a list of check boxes to select assignees and update (or delete) the relationship (assigning model).

We can use collection_check_box for this purpose.

= f.label :task_name

= f.text_field :task_name = f.label :assignees

= f.collection_check_boxes :assignee_ids, current_user.contacts, :id, :name

And allow assignee_ids as part of parameters in controller

def task_params

params.require(:task).permit(:task_name, :assignee_ids => [])

end

You can image that once we receive params[:task][:assignee_ids] in task controller, we need to create new associations for new assignees and remove old ones. It would looks like this:

old_ids = task.assignees.pluck(:id)

new_ids = params[:task][:assignee_ids].compact.collect(&:to_i) (new_ids-old_ids).each do |x|

task.assignings.create(contact_id: x)

end (old_ids-new_ids).each do |x|

task.assignings.find_by(contact_id: x).destroy

end

But actually you need to do nothing. Yes, NOTHING ! task.update(task_params) will work it out. Just be sure that assignee_ids in form (parameters) match the assocation name has_many assignees .

I do not know when this style of update is supported. But it works in Rails 6.1.
Best practice security exceptions
By: Marcus Baguley
Tags: Continuous Improvement, Security, Rails, Exception, Web Development

Best practice security exceptions

You should be following OWASP’s best practice security recommendations and taking CSFR precautions in your production web applications.

However, these security features can adversely affect real users and you may notice ActionController::InvalidAuthenticityToken exceptions appearing in your production runtime which can be challenging to reproduce.

The following scenarios have been identified that can create these exceptions in your production environment for ‘real’ users.

Stale authenticity token on a form

The User session has timed out. The user then logs back in and back pages to a form which contains an authenticity token for the old session. The browser will present the new session cookie when the form is submitted. Boom.

To resolve this the page form page should be reloaded from the server with the new session. Setting the following response headers will cause the browser to reload the form, and not use a cached version on disk.

# nginx config

add_header "Cache-Control" "max-age=0, no-cache, no-store, must-revalidate";

add_header "Pragma" "no-cache";

add_header "Expires" "-1";

User leaves a stale form open AND in a new tab logs out and logs in

In this case a new session is established, but the old page still exists and hence contains the old authenticity token (it doesn’t get a chance to reload using cache headers detailed above). You really don’t want someone submitting an old form on a new session so the authenticity token is kind of giving you a good side effect in this situation.

This is a UX question as well as a technical one and there are several options to prevent the user from getting an error.

Option 1 rescues the exception and does a GET request to refresh the page. The page will then load with a valid authenticity_token.

Option 2 uses the reset_session option to always brutally force them off the session. No logging occurs here which is unfortunate if you want monitor for real CSRF events. The page flow will then be caught by an authorize action in the request chain.



# option 1 rescue_from ActionController::InvalidAuthenticityToken do |_exception|

flash[:alert] = 'The session has been reset. Please try again.'

redirect_back fallback_location: root_path

end # option 2 protect_from_forgery with: :reset_session
ruby常見套件-Paranoia（偏執狂）
By: Mino Chen
Tags: Rails, Paranoia

Learn more. Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Make Medium yours. Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore
rails 常用套件 — pundit(權限管理套件)
By: Mino Chen
Tags: Rails

Learn more. Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Make Medium yours. Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore
rails常用套件 — kaminari (幫你長出分頁)
By: Mino Chen
Tags: Rails, Kaminari

Learn more. Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Make Medium yours. Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore
Links con informacion interesante para tener a mano
By: Ivan Gonzalez
Tags: Leadership, Ruby, Git, Coding, Rails

How to Write a Git Commit Message

If you browse the log of any random Git repository, you will probably find its commit messages are more or less a mess…
前後端分離 Vue + Rails 後端 HTTP token 認證設置
Tags: Http Authentication, API, Vue, Rails, Token

因為前端要來打我們的 api，但不是每個人都可以打，所以要設權限

app > controllers > api > v1 > api_controller.rb

module Api

module V1

class ApiController < ApplicationController

protect_from_forgery with: :null_session

before_action :authenticate_token



def authenticate_token

@api_access_key, = ActionController::HttpAuthentication::

Token.token_and_options(request)

@auth_token = request.headers[:HTTP_X_API_TOKEN]

render_unauthorized and return unless @auth_token

render_unauthorized if @auth_token != ENV['XXX']

end

def render_unauthorized

headers['WWW-Authenticate'] = 'Token realm="Application"'

render json: 'Access denied', status: :unauthorized

end

end

end

end

CSRF （Cross-site request forgery）跨站請求偽造

攻擊的細節

跨站請求攻擊，簡單地說，是攻擊者通過一些技術手段欺騙用戶的瀏覽器去訪問一個自己曾經認證過的網站並執行一些操作（如發郵件，發消息，甚至財產操作如轉帳和購買商品）。由於瀏覽器曾經認證過，所以被訪問的網站會認為是真正的用戶操作而去執行。這利用了web中用戶身份驗證的一個漏洞：簡單的身份驗證只能保證請求發自某個用戶的瀏覽器，卻不能保證請求本身是用戶自願發出的。 （From Wiki）

為了保護使用者，伺服器端必須要有合適的防禦措施

在 Rails 裡，不能透過內建的檢查機制來防治 CSRF 所以我們要先關閉 CSRF 的檢查

protect_from_forgery with: :null_session

Token 檢查

before_action :authenticate_token def authenticate_token

@api_access_key, = ActionController::HttpAuthentication::

Token.token_and_options(request)

@auth_token = request.headers[:HTTP_X_API_TOKEN]

render_unauthorized and return unless @auth_token

render_unauthorized if @auth_token != ENV['XXX']

end

def render_unauthorized

headers['WWW-Authenticate'] = 'Token realm="Application"'

render json: 'Access denied', status: :unauthorized

end

這裡我們定義一個驗證 token 的方法

@api_access_key, = ActionController::HttpAuthentication::

Token.token_and_options(request)

token_and_options

這個 API 是專門檢查 http 的 Authorization 這個 header，它會自動幫你把 Authorization header 的值拆出來，因為 header 帶來的其實是一個字串，他會自動幫你 parse。

HTTP認證（HTTP Authentication）

headers['WWW-Authenticate'] = 'Token realm="Application"'

上面的這個方法 對照 Syntax

WWW-Authenticate: <type> realm=<realm>[, charset="UTF-8"]

所以 Token 是 type，” Application ” 是作用範圍

還有一個部分是給前端的 token 我們可以在 rails console 內下

SecureRandom.hex(16)

生出一組亂碼給前端使用，可以把亂碼放在 application.yml 內

Rails 6 已經有支援可以將密碼放在 credentials.yml 內，但是由於我們的專案要在 Heroku 部署，Heroku 沒有支援，所以就還是放在 application.yml

但是你要在 heroku 環境變數設置 RAILS_MASTER_KEY

下一篇 前後端分離，如何不用 devise 做出一般登入及第三方登入
Library Vulnerability Checks
By: Damien Burke
Tags: Rails, Vulnerabilities, Gems

Library Vulnerability Checks

Published: December 8, 2020

This is part of The Annotated Guide to a New Rails App, a list of recommendations to make developing your Rails app more productive and joyful.

In this article, we are talking about checking for library vulnerabilities.

When

You should check for library vulnerability before creating a production environment.

Why

As soon as you make your application available on the Internet, if there is a vulnerability in one of the libraries you used, it is possible that that vulnerability could be used to compromise your application.

How

Use bundler-audit to check for known security vulnerabilities in your gems.

To install, add gem 'bundler-audit' to the development section of your Gemfile and run bundle .

To run the checks, use the command bundle audit .

Update any gems with vulnerabilities.

Alternatives

There are services that will monitor your running applications for libraries with known vulnerabilities. They are a much better solution for applications that are not under active development or that, for some other reason, go a long time between updates.
Walking Through the Login Process
By: Ivan Luk
Tags: JavaScript, Rails Routes, Rails, Login, Jwt Token

Pretty much every website requires login so if you ever wonder what that process is like in an app with JavaScript frontend and a Rails backend, here is a walk-through of the steps.

Username, password, and a Login button. These are usually the first things users interact with when they visit a website. What is behind the scene when the credentials are entered and the button is clicked? First, let’s start from the JavaScript Login component.

We have two text inputs for username and password and a submit type input, which is the Login button. When the Login form is submitted, the loginUser function ins invoked. This is our next stop in this walk-through.

We get an event (e) in the submit action and the first thing we do is to prevent the refresh by invoking the preventDefault method. Then we start the journey to the backend by preparing the URL that we need to visit and the request object that is needed when the fetch call is made. Since this is a login and we need to supply data (username and password) to the backend, we need to make this Post method as we are posting data for Rails backend to process. Since we specified /users as the path, let’s see what happens when we get to the backend.

When dealing with a Rails backend, a path is basically a route in a Rails app. In order for the app to know what to do we need to draw the proper routes to tell the app what to execute when the user visits a certain path. This is what I have in the routes.rb file.

Since we issued a Post call with the path /users, the above tells Rails that we need to go to the “users” controller and execute the “create” method. Let’s now go there to see what happens.

In this method, we first try to locate the user based on the username entered. If found, we then try to authenticate based on the provided password. Once authenticated, we create a JSON web token (jwt) for the user browser to save so the user can avoid logging in as long as the jwt is presented in subsequent sessions. Along with the jwt, we send back all the data the frontend app needs in JSON format by executing a render. We can now go back to the Login component on the frontend app.

Now we are on line 73. We receive our user data back from the backend along with the jwt. If there is no error, we first store the token in local storage (line 82) followed by updating the Redux store with the data needed for the user logged in. The two subsequent functions are just extra data retrievals from the backend. Since we just receive a fresh token, we will put it to good use when fetching more backend data. At this point we have completed the login process and we are ready to display any appropriate data on whatever webpage needed. This is accomplished by simply executing a “this.props.history.push(‘/xxxxx’)” to tell React router who component to render next.

There you go, a quick walk-through of the login process from JavaScript frontend to Rails backend and back.
Rails 裡常見的ruby語法跟方法
By: Mino Chen
Tags: Rails, Ruby

Learn more. Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Make Medium yours. Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore
Git blame — Ignoring bulk change commits
Tags: Ruby, Git Blame, Git, Rail, Rubocop

RuboCop

RuboCop is a Ruby static code analyzer (a.k.a. linter) and code formatter. Out of the box it will enforce many of the…
My JavaScript Rails Project
By: Benjamin Jonah Mallard
Tags: CSS, Ruby, Json, JavaScript, Rails

I was recently asked to create a Single Page Application using HTML/CSS & JavaScript as the frontend, and Ruby on Rails as the backend. I really enjoyed doing this project because It really helped me understand how useful JavaScript can be in altering and updating web pages.

I used JavaScript to completely render the backend data in a neat orderly way to the web page using an Event Listener called by “onDomContentLoaded” with a little help from Rails, and HTML/CSS. Rails mainly helped with connecting my web page to a database. Although, it did help with the routing and displaying all the data to the page using Rails Server.

I was also able to render to the page Vehicles of a specific category. This was especially informative because I was able to let JavaScript operate on the sorting part of it by selecting and rendering cars, trucks, or recreational vehicles by accessing their ID. While also submitting the selection using the “onChange” Event Listener.

It was also nice to learn about using fetch to access information and sending that to the backend while also using promises to access the information passed in and rendering the data with JSON (JavaScript Object Notation).
Things I Would Have Done Differently
By: Jack Tawil
Tags: Coding, Rails, Development, React, Full Stack

Services/utils.js Fetch Response Handling

When I know there’s going to be many fetch requests in a particular project, I love to place all of the fetches in one central file. I typically create one variable called BACKEND that is called in all of the fetches, and upon deployment it’s easy to swap out the backend URL.

Something I would have done differently is create a single function to handle each of the fetch responses. That way if the response is a 200 status it returns response.json(), other response statuses may send out an alert instead. This would help with errors during development and can be recycled across multiple projects. I would also be able to more easily toggle the console logs on and off for fetch requests.

CSS

I would have liked to keep styling uniform throughout the application. CSS can be a real pain and in-line styles are a bit easier. We should have chose a single path — either in-line or CSS, not both.

Class Names

Naming classes could be tricky, and if you’re not following a pattern it could be really annoying to style using CSS or SCSS. We should have had followed a naming convention such as BEM (Block, Element, Modifier).

Organization

I always try to keep code clean, organized, and DRY. I feel as though we could have done a better job keeping things clean from the start. Otherwise, it all builds up and debugging can be a real pain. In particular, one should never write functions that are lengthy- you’re only creating more work for yourself later.

Deadlines

When creating projects, it’s important to make deadlines and set goals — otherwise it’s an open-ended, never-ending project. We maybe should have set our goals a bit lower from the start and expand outward from there.
Rack-CORS and You!
By: Kevin Gleeson
Tags: Cors, 1950s, Ruby on Rails, Rails, Development

To get an understanding of why we’re getting this error. It’s important to know what CORS is and what it does for our applications. For starters, CORS stands for Cross Origin Resource Sharing. CORS is essentially a security feature located in our browsers that limits access to our apis from the frontend by monitoring which requests can be allowed through to our backends.

Sounds simple enough But what about that error?

Don’t be scared, Little Suzie. We’ll learn about that error now!

According to MDN “CORS failures result in errors, but for security reasons, specifics about the error are not available to JavaScript. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser’s console for details.” This is the main reason why you’re having trouble accessing your backend through your frontend.

Typically when we look at our console, we see the error from the top of the article. Javascript has an issue with this sort of access and if you’re building out a full stack application you’ll likely need to set up your backend the following way:

Step 1. Install the “rack-cors” gem

That’s as simple as including gem ‘rack-cors’ in your gem file and doing a fresh bundle install.

Step 2. Find cors.rb

Go to your config file, and inside the initializers find the cors.rb file.

Step 3. Set cors to allow all origins.

When you go to your cors.rb file you’ll see something that looks like this:

Take a look at line 10, Little Suzie.

What line 10 is saying is that our backend will only allow requests coming from ‘example.com’. All we need to do to change this is allow our origins to come from anywhere. This can be done by replacing ‘example.com’ with an asterisk. ‘*’

You can edit out some of the methods that you want users to have access to this way, too!

Now our backend should be able to communicate properly with our frontend.
Deploy Your First Rails App With Heroku
By: Lian Nivin
Tags: Ruby, Heroku, Deploy, Rails, Web Development

If you are starting to learn this beautiful framework, you will be interested in taking your first project, demo or task to production, which is what really matters when developing. Also, you can do it for free!

Why Heroku?

Heroku helps you forget about the infrastructure aspect that exists behind as well as the security aspects and also manages all this for you in the cloud. In other words, you only worry about your application working and having your Config Vars set correctly.

Requirements

Make sure you have this ready before you start:

A hosted repository on GitHub.

A free Heroku account.

Ruby 2.3.5 version or higher installed locally.

Bundler installed locally.

Heroku CLI.

If you want to start without any previous repository, you can download one from here or just clone it from the terminal:

$ git clone git@github.com:lnivin/rails-crud-app.git

Deploying Process

We’ll use Heroku CLI in order to streamline our process. For static pages, you just need to follow this few steps:

Login

At this step, you will be redirect to a login page from Heroku. All you need to do is to push your credentials as usual.

$ heroku login

2. Create App

Add a name to your App so that you will recognize it when it is published on the Internet. Make you are stand on the root of your project.

$ heroku create my_test_app_name

If you regretted about the name you gave to your App, don’t worry, use this command as many times as you like:

$ heroku apps:rename another_name_for_my_app

3. Push on Heroku

In this case we are deploying the ‘‘main’’ branch of our project. But in your case, you can decide what other branch you want to deploy, just replacing it.

$ git push heroku main

4. Open your website

Running this command, automatically will open your deployed project on the browser.

$ heroku open

You finished! But, maybe you want to use any database to use CRUD (Create, Read, Update and Delete) operations in your App. In this case, you need to know that Heroku no longer supports “SQLite” as a production database, which is the default database for Rails.

A way to solve this is to add a production environment configuration in your Gemfile, like this:

Setup Environment Configuration for Rails

In my case, I added PostgreSQL gem for my production database and keep the default database for the development environment. Then, run bundler without consider your production environment:

$ bundle --without production

Almost you finished, just need to update your code on your remote repository and then run the database migrations for the production environment:

$ heroku run rake db:migrate

You are done! Now, open again your browser to see changes.

As final words, I suggest to you to keep learning Rails if you are starting on this. You will really notice the time you save building websites in comparison with another technologies available on the market.
Convention over Configuration made easy.
By: Daniel Susviela
Tags: Computer Science, Software Engineering, Software Development, Rails, Convention Over Config

Image credit to ACI

Before covid, ages ago I know, a friend of mine asked me whether her 60lts bag could count as a carry-on luggage for her flight, and that way avoid the cumbersome process of checking her baggage. My answer was the one she least expected; “It depends”. She was baffled by the fact that there’s no standard size.

Unfortunately, that’s the hard truth, each airline has it’s own set of rules for what does and what doesn’t constitute as a carry-on bag. Adding insult to the injury, these rules are completely independent of the aircraft’s model. American Airline’s 747 Boeing may ask for a 21” x 12” x 9” bag while the same plane operated by Delta may ask for carry-on to be no bigger than 23” x 14” x 9”. My friend had to make a decision, either risk having her bag checked in or buy a smaller one. She was being a victim of the lack of convention.

Let’s get rid of the unnecessary decisions

Convention over configuration seeks to make our lives easier by effectively decreasing the set of inconsequential decisions to a minimum. This, in turn allows us, developers, to focus in the aspects that really matter.

For instance in Rails when we use the rails scaffold command we get several files generated for us. We don't get to decide their name or their location as all of that is irrelevant. This allows us, developers, to think on the attributes of the entities we’re creating. We don't care about the size of the luggage, we care about its contents.

Another positive aspect to keep in mind is that it favors the comprehension of alien code as the convention may help understand how it behaves. This can go a long way when you’re scrambling to understand existing or new code made by others.

But wait someone has to be making those decisions, right? I hear you ask. Yes, typically a group of experts, or the creators of the framework being used. For instance, in Rails that would be the core team. Continuing with the analogy, maybe the FAA should set the standard size of a carry-on.

The price to pay

As everything in life, Convention over Configuration is not free of charge. Adapting to a new convention takes time, and sometimes it makes it very confusing as to why things work for newer developers. Also there’s people that prefer to have all of the things laid out for them, Convention over Configuration more often than not, does the exact opposite.

Also as applications tend to grow, the problems start to become more and more specific which inevitably creates the necessity to stray away from the convention. This not only overthrows the benefits but may make the code more difficult to understand by others. Also some frameworks make your life hell if you stray further enough from what’s the “correct way” of doing things.

Made easy

Convention over Configuration is a nickname given to the practice of setting rules to be followed within a framework. Think of it as a tacit agreement between you and the tool.
Devise gem in Rails
By: Virendra Pratap Samrat
Tags: Ror, Ruby, Ruby on Rails, Gemfile, Rails

add gem file gem 'devise' to Gemfile, and then running: $ bundle install then run $ rails generate devise:install after that Create your User Model. $ rails generate devise USER then run $ rails db:migrate Generate your View $ rails generate devise views:users

then show your User login use

<p class=”navbar-text pull-right”> <% if user_signed_in? %> Logged in as <strong><%= current_user.email %></strong>. <%= link_to ‘Edit profile’, edit_user_registration_path, :class => ‘navbar-link’ %> | <%= link_to “Logout”, destroy_user_session_path, method: :delete, :class => ‘navbar-link’ %> <% else %> <%= link_to “Sign up”, new_user_registration_path, :class => ‘navbar-link’ %> | <%= link_to “Login”, new_user_session_path, :class => ‘navbar-link’ %> <% end %> </p>

This is a basic setup, but you can read more on how to customize Devise and utilize the included helper methods here!
Why I used Rails sessions instead of JWTs
By: Zaharia Anton
Tags: Auth, API, Jwt, Authentication, Rails

After doing my research about JWT tokens, I decided to enable Rails sessions and start using them for my authentication system. What changed my mind was an article I found on cryto.net:

If an attacker manages to inject a malicious script into your front end (which is vulnerable to XSS), then they can use that script to make HTTP requests to your server (directly from the user’s browser) and your precious httpOnly cookie (containing the user’s valid session ID) will be attached to every request so the server will service them without suspecting anything.

How I enabled sessions if my app was using an API Rails app you can find out here: Rails sessions does not persist?

Creating an app that will not be used a large number of users at the same time will not have any problem handling the cookies on the server-side.

That being said, my app is ready to receive users, and they can perform the authentication parts securely. But, no content yet. Web sockets and their implementation fill follow.
Rails裡的session和cookie
Tags: Rails, Ruby, Ruby on Rails

Learn more. Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Make Medium yours. Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore
Creating Rails methods with SQL: Part II
By: Ben Dunjay
Tags: Ruby, Backend Development, Codingbootcamp, Rails, Sql

So let’s start with building our instance from the database query.

Our database table is comprised of rows and when we query the database we will get an array/lines of arrays dependent on the query you choose. This method is fairly straightforward but easy to get wrong.

When I query the array I will get something like this:

So, our method is simply going to be re-organising our array. We want a method that takes a row of data and then assigns each element.

Here we are using a class method. Then I am assigning the attributes in the same order as the initialization and then calling self.new or User.new with the attributes. Perfect! This is a method that is likely to be used regularly in some of our other methods as we query the database for more and more data.
Use a Rails Linter
By: Damien Burke
Tags: Rails, Ruby, Linter

Use a Rails Linter

Published: December 1, 2020

This is part of The Annotated Guide to a New Rails App, a list of recommendations to make developing your Rails app more productive and joyful.

In this article, we are talking about using a Rails linter.

When

The longer you wait to add a linter, the more work you will have to correct style errors that have accumulated. For that reason, I recommend adding a Rails linter as early as possible.

Why

A Rails linter like the Rails Best Practices gem can catch and sometimes correct common mistakes and problems in Rails code.

How

To install, add rails_best_practices to the development section of your Gemfile.