20190830のRubyに関する記事は16件です。

█║▌Software Defined to Spatial Defined Networking

While software defined networking has proven its value, SynchroKnot has taken software defined networking to a whole new dimension with Spatial Defined Networking.

Spatial Defined Networking is made up of SynchroKnot's core networking component called Satellite Tree Protocol, which is an enhancement to the IEEE standard [ 802.1D (1998|2004), 802.1W ] while keeping the core semantics in place.

This simplistically means, you can use any commodity X86_64 Desktop/Workstation/Server/Embedded device and connect them to eachother.

There is no need to purchase physical or virtual switches and routers or any of their licenses [Eg. Cisco, Juniper etc].

Satellite Tree Protocol is the core networking component of the SynchroKnot Cloud Computing and Data Center Decentralization software.

In brief, the SynchroKnot software transforms any server, workstation, desktop or embedded device into a decentralized cloud or data center [data decenter].

There are various demonstration videos depicting its workability, performance, security and scalability on synchroknot.tokyo

Here are some of the highlights of the SynchroKnot Satellite Tree Protocol:

■ Automatic - Mission-Critical - Resilient - Self-Sustaining - Self-Healing - Seamless Scaling Without Down-Time - High-Performance.

■ Nothing to configure or manage.

■ Enhancement to the IEEE standard [ 802.1D (1998|2004), 802.1W ] while keeping the core semantics in place.

Standard Layer 2 Ethernet remains pure, untouched and unmodified without frame encapsulation, additional headers or other forms of tinkering.

■ Improving upon and applying the globally accepted IEEE standard found in network switches onto Spatial Fabric Satellites. Network is no longer a separate complex component with separate hardware and licenses, but is now built right in with nothing extra that needs to be done.

■ Depending on your need and/or requirement, you now have a logical straight-forward option and ability to eliminate Top-of-the-Rack, Spine, Leaf, Edge, Aggregation and Core Switches & Routers, along with their respective licenses.

■ Large-Scale, High-Performance Layer 2 Environment with a single instance of Satellite Tree Protocol with support for single, double and triple stacked VLANS.

■ Does not cause a network-wide outage on failure of link(s) as experienced with regular Spanning Tree Protocol [ STP ] and Rapid Spanning Tree Protocol [ RSTP ].

■ Recovery from failure is, in most cases, in sub-milliseconds to about 1.5 seconds depending on the nature of failure [ single / multiple links ] and the distance from the point(s) of failure. Traffic that does not traverse the path where failure occured is generally not affected by the failure at all.

■ Intelligent Layer 2 Optimized Cost Multipath forwarding logic based on local intelligence chooses the best link with the shortest optimal path in normal operation, congestion and on link failure.

■ Multiple ANY-to-ANY Layer 2 routes allow you to add and remove hardware transparently without turning off whole or sections of the network, as experienced with switches and routers in networks today.

■ Zero Configuration.

How about never having to endure countless hours of pain configuring, managing and maintaining physical Ethernet ports, trunking and ACLs and other aspects? How about plugging one end of Ethernet cable into ANY physical port of a commodity hardware and connecting the other end to ANY physical port of another commodity hardware and that's it - nothing to do.

■ Get the best of cost, low latency, bandwidth and performance in multiple directions, not just East-West / North-South with the help of SynchroKnot Multi-Dimensional topology.

■ SynchroKnot Multi-Dimensional topology is a dynamic mix and integration of proven network topologies which are used as a primary backbone in High Performance Computing and Supercomputing. These include Ring, 2-D, 3-D and many other custom topologies optimized for cost, performance and simplified cabling.

■ Single-length cable for the entire cluster. No long haul cables. No expensive power-consuming optical cables.

■ Very low CPU usage.

Apart from all these features, there are multitude of extra security features to choose from on top of the Satellite Tree Protocol.

More information is available at:
■ synchroknot.tokyo
■ synchroknot.org

You are encouraged to share your knowledge with others! :rocket:

SynchroKnot-Satellite-Tree-Protocol-Direct-Connect-Architecture.png

SynchroKnot-Multipath-Ethernet-Routes-and-Links-for-Mission-Critical-Operations.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

railsにおけるnio4rのエンコーディングエラー

rails new 時、

Encoding::CompatibilityError: incompatible character encodings: Windows-31J and
UTF-8

とエラーが出た。
nio4rをインストールしろとの指示も出るがすでにインストール済みである上、インストールし直しても変わらず。

自分の解決法

ディレクトリが、ひらがな名だった…。
nio4rはUTF-8がデフォルトなので、
ディレクトリを、「Rails」などの適当なアルファベット名に変更で解決した。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

herokuへのデータベースのリセットとサンプルデータの生成

heroku上のデータベースをリセットしたい場合

heroku pg:reset DATABASE

リセット後

heroku run rails db:migrate
heroku run rails db:seed

結果は同じだがこちらのコードでも大丈夫↓

heroku run rake db:migrate
heroku run rake db:seed
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

idを変更してオリジナルURLを作ってみた(Rails)

はじめに

アプリケーション開発をしていて簡単に推測できるURLを利用したくないことってありますよね。
この記事では、id(例えばユーザーのid)をランダムな文字列に変更してオリジナルURLを作成します。
URLは次のようなものを目指します。

https://xxxxx.com/users/7b7375d7c10c97901ce

環境

windows(64bit)
ruby 2.6.3p62
Rails 5.2.2
Cloud9上で開発

手順

今回はUserモデルのuserのidをランダムな文字列に変更していきたいと思います。

1. UserモデルにランダムURL用のカラムを作成

Userモデルにurl_tokenというテーブルを作成します。
このurl_tokenが先ほどのランダムな文字列(=7b7375d7c10c97901ce)に対応します。
まずはマイグレーションファイルを作成し、DBに反映します。

$ rails generate migration add_url_token_to_users url_token:string
$ rails db:migrate

2. URL中のidをurl_tokenに変更

$ rails routes
                   Prefix Verb   URI Pattern                                                                              Controller#Action
                    users POST   /users(.:format)                                                                         chats#create
                 new_user GET    /users/new(.:format)                                                                     users#new
                     user GET    /users/:id(.:format)                                                              
   users#show
                          DELETE /users/:id(.:format) 

という感じになっていると思います。
この:idを:url_tokenと変更します。

まずはルーティングを変更します。

config/routes.rb
Rails.application.routes.draw do
  resources :users, param: :url_token
end

usersのresourcesに、paramオプションでurl_tokenを設定します。

次にモデル内でto_paramメソッドを用いてurl_tokenを指定します。

app/model/user.rb
class User < ApplicationRecord
  validates :name,      presence: true
  validates :url_token, presence: true, uniqueness: true

...

  def to_param
    url_token
  end
end

ルーティングを確認すると:idが:url_tokenに変更されています。

$ rails routes
                   Prefix Verb   URI Pattern                                                                              Controller#Action
                    users POST   /users(.:format)                                                                         chats#create
                 new_user GET    /users/new(.:format)                                                                     users#new
                     user GET    /users/:url_token(.:format)                                                              users#show
                          DELETE /users/:url_token(.:format) 

3. コントローラーでデータを取得する

userをidではなくurl_tokenを用いて取得するためには次のようにします。

@user = User.find_by(url_token: params[:url_token])

このとき、url_token:の部分をid:としないよう気を付けてください。
今まで行った操作は、Userモデルにurl_tokenカラムを作成し、URL内の:idを:url_tokenに変更しただけであって、idそのものをurl_tokenに変更したわけではありません。なのでちゃんとuseのidは存在します。コンソールで確かめると分かると思います。

4. ランダムな文字列を生成する

ランダムな文字列を作成するには、Userモデル内でattributeとSecureRandom.hex(10)を使います。
attributeはモデルの属性の定義や更新を行えます。今回ランダムな文字列はstring型として扱います。
またSecureRandom.hex(10)はランダムな文字列を生成しています。
そして次のようにモデル内で記述します。

app/model/user.rb
class User < ApplicationRecord
  attribute :url_token, :string, default: 

  validates :name,      presence: true
  validates :url_token, presence: true, uniqueness: true

...

  def to_param
    url_token
  end
end

今回はデフォルトにSecureRandom.hex(10)を設定しています。

これでもうオリジナルのURLは作成されているはずですが、いくつか補足しておきます。

pathの使い方

例えばユーザーページのリンクをview内で記述するときは次のようにします。

<%= link_to "ユーザーページ", user_path(url_token: @user.url_token) %>

Strong Parametersの使い方

Storong Parametersを設定するときもいつも通りurl_tokenをカラムの一つとしてpermitに加えてください。

def event_params
  params.require(:user).permit(:name, :email, :url_token)
end

おわりに

URLをオリジナルにするのはそんなに難しくないと思います。
ただネストしたりだとか、seeds.rb、fixureの作成とかで手間取るかもしれないので頑張ってみてください!何か間違いがありましたら、ご指摘ください。

参考文献

(1) "RailsでQiitaみたいなランダム文字列のURLを使う方法". Qiita. https://qiita.com/saitoeku3/items/dd91a290c695aa63e34f, (参照 2019-8-30)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

大学2年生のオリジナルWebアプリケーション開発8日目

今日の流れ

  1. イベント一覧の表示(続き)
  2. フォーム作成

前回Eventモデルを作成し、作成されたイベントの一覧を表示させ日付の表示を行いました。
今日はその続きでCSSを整えたり、カラム名の変更、そしてイベントを作成するためのフォームを作成しました。

1. イベント一覧の表示(続き)

前回までにほとんどイベント一覧は完成していたのですが、気に入らない部分が二つありました。それは

⑴ イベント名のカラム名がeventであること
⑵ 一覧表のviewが見づらいこと

です。

(1) カラム名変更

Eventモデルのカラム名がeventだと、名前を取り出すときなどは、

@event.event

としなくてはならず、わかりづらかったので、カラム名の変更は以下のようにしました。

モデル名 変更前のカラム名 変更後のカラム名
event event event_name

カラム名変更の手順をまとめました。

migrationファイルの作成

まずはmigrationファイルを作成します。

$ rails generate migration rename_event_column_to_events #eventがカラム名, eventsがモデル名

migrationファイルを編集

db/migrate/○○_rename_event_column_to_events.rb
class RenameEventColumnToEvents < ActiveRecord::Migration[5.2]
  def change
    rename_column :events, :event, :event_name
  end
end

そして最後にDBに反映させます。

db:migrate

(2) borderの角を丸くする

borderの角を丸くするのは簡単でしたが、今まで使ってこなかったのでその方法を自分用に残しておきます。

border-radius: 10px;

こうするだけですね。実際に以下のように使いました。

app/assets/stylesheets/custom.scss
li {
    padding: 10px 0;
    margin-top: 5px;
    border: 1px solid #e8e8e8;
    border-radius: 10px;
  }

実際の画面ではこんな感じです。
イベント一覧.png

画像は当日撮ったものではなく、後日撮ったものなので回答や削除などまだ8日目にはコードにないものもありますが、うまく角が丸くなりました。

2. フォーム作成

フォーム作成自体は難しくなかったのですが、Railsチュートリアルとはいくつか異なる点がありました。

(1) 日付フォーム
(2) placeholder

(1) 日付フォーム

ユーザーにはイベントの日時を設定してもらう必要があるため日付を選択するフォームを作成しなければなりませんでした。
フォームに取り掛かる前は、カレンダーを自作するか、gemでも使うから難しいだろうと考えていました。しかしふたを開けてみたらなんとRailsに用意されているdate.filedタグを使ったらカレンダーもついてきました!ちょっと拍子抜けでした笑。
実際には以下のようにコードを書くとできます。

<%= f.label :date, "日付" %>
<%= f.date_field :date, class: "form-control" %>

カレンダー.png

(2) placeholder

実際にユーザーに使ってもらう時、記入例があるとわかりやすいと思いますので、フォームにあらかじめ記入例を入れておきました(ユーザーが記入すると消える)。

その方法も簡単で以下のように、あらかじめ入れておきたい言葉をplaceholderに続けて記述するだけです。

<%= f.text_field :event_name, class: "form-control", placeholder: "例)練習・旅行・飲み会" %>

すると上の写真のイベント名のフォームのように、あらかじめ記入例が入れられるようになります。

終わりに

イベントの一覧とフォームを完成させることができました。
次はevent_idをオリジナルの文字列(オリジナルのURLを作成する)やAnswerモデルの作成などです。気合い入れていきます!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsでのランダム表示を実装してみた 簡単!

初めに

ポートフォリオを作成するにあたり、ランダム表示を実装しました。
プログラミング歴4ヶ月の初学者でも簡単に実装できたのでメモを残します。
もし良かったら、参考にしてみてください。

環境

・Ruby '2.3.8'
・Rails '5.2.3'

前提条件

bookというテーブルに、titleとcontentカラムがあるとします。

実装方法

実装方法はは簡単でコントローラーとビューに記述するだけです。

コントローラー

books_controller.rb
#5件表示
@random = Book.order("RANDOM()").limit(5)

#全件表示
@random = Book.order("RANDOM()").all

limitを設定することで表示される件数を指定することができます。

注意点

mysqlを使用しているとエラーが発生します。
その場合は、以下のように記述する必要があります。
(*RANDOMをRANDにしないといけません。)

books_controller.rb
#5件表示
@random = Book.order("RAND()").limit(5)

#全件表示
@random = Book.order("RAND()").all

ビュー

index.html.erb
<% @random.each do |book| %>
  <%= book.title %>
  <%= book.content %>
<% end %>

以上で実装完了です。

参考資料

railsでランダムに複数のレコードを取得する

最後に

たったこれだけで実装できます。
もし良かったら試してみてください。

最後までお付き合い頂きましてありがとうございます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsでのランダム表示を実装してみた 簡単![初心者向け]

初めに

ポートフォリオを作成するにあたり、ランダム表示を実装しました。
プログラミング歴4ヶ月の初学者でも簡単に実装できたのでメモを残します。
もし良かったら、参考にしてみてください。

環境

・Ruby '2.3.8'
・Rails '5.2.3'

前提条件

bookというテーブルに、titleとcontentカラムがあるとします。

実装方法

実装方法はは簡単でコントローラーとビューに記述するだけです。

コントローラー

books_controller.rb
#5件表示
@random = Book.order("RANDOM()").limit(5)

#全件表示
@random = Book.order("RANDOM()").all

limitを設定することで表示される件数を指定することができます。

注意点

mysqlを使用しているとエラーが発生します。
その場合は、以下のように記述する必要があります。
(*RANDOMをRANDにしないといけません。)

books_controller.rb
#5件表示
@random = Book.order("RAND()").limit(5)

#全件表示
@random = Book.order("RAND()").all

ビュー

index.html.erb
<% @random.each do |book| %>
  <%= book.title %>
  <%= book.content %>
<% end %>

以上で実装完了です。

参考資料

railsでランダムに複数のレコードを取得する

最後に

たったこれだけで実装できます。
もし良かったら試してみてください。

最後までお付き合い頂きましてありがとうございます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsでサブドメインに対応させる方法

はじめに

こんにちは!
こちらの記事では、RubyOnRailsでサブドメインに対応させる方法をご紹介したいと思います^^

サブドメインを設定することによって、localhost:3000から脱却し、mysite-onaga.comや、one.mysite-onaga.com、two.mysite-onaga.com、three.mysite-onaga.comなど好きなドメインを設定できます!

しかし、こちらのドメインはあくまでローカル(自分のPCだけ)だけで使えるものになりますのでご注意ください。。サイトを公開するには、お名前.comさんなどでドメインを取得して設定する必要があり、こちらはご紹介しておりません。

前提:Rails環境構築済み, Mac

URLをlocalhost:3000以外に変更する

はじめにPCの設定そのものにlocalhost:3000にサブドメインを設定してあげます。設定済みの方は飛ばしていただいて大丈夫です。

Macの場合、ターミナルを開いて、vi /etc/hostsで設定ファイルを開きます。人によっては書き込み権限がなく、sudo vi /etc/hostsにする必要があるかもしれません。

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
127.0.0.1       mysite-onaga.com one.mysite-onaga.com
255.255.255.255 broadcasthost
::1             localhost

localhost:3000はIPアドレスにすると、127.0.0.1となります。
ですので、hostファイルの127.0.0.1の行に自分で設定したいサブドメインを記述します。

Railsでrouteを設定する

前章の設定で、URLをmysite-onaga.comなどでアクセスすることで、localhost:3000で開いていたページを開くことができるようになりました。しかし、今回設定したサブドメインは3つあります。せっかくなので、サブドメイン別にrouteを設定していこうと思います。
例えば、get 'home/zero'はmysite-onaga.comでしかアクセスできないように、get 'home/one'はone.mysite-onaga.comでしかアクセスできないようにすることができます。

やっとこRailsのroutes.rbを編集していきます!

### routes.rb ###

# mysite-onaga.com
constraints subdomain: '' do
  get 'home/zero'
end

# one.mysite-onaga.com
constraints subdomain: 'one' do
  get 'home/one'
end

以上の設定により、http://mysite-onaga.com/home/zerohttp://one.mysite-onaga.com/home/oneにアクセスできるようになったかと思います^^

rails routesコマンドを打つとパスがちゃんと設定されているか確認できると思いますので、試してみてください。

終わりに

以上がRailsでサブドメインに対応させる方法になります!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Railsでchart.jsに変数を入れる方法

はじめに

19年6月からプログラミングの勉強をはじめているものです。
作成したアプリでchart.jsを使用し、変数を入れるところに苦労したので書いてみます。

chart.jsの導入

導入に関してはこちらを参照、大変分かりやすくグラフの導入部までは簡単にできます。

グラフに変数を入れる。

例えば、毎日の運動時間を測るアプリで、運動時間と日付を棒グラフで作る際は、このような感じになります。

前提 

UsersとSportsとテーブルがある。
UsersとSportsは親子関係で一対複数の関係
Sportsにはsport_day(データ型はdate)とsport_time(データ型はfloat)のカラムを持つ
*created_atでも問題なし

Controllerからです。

X軸はこちら、日付を配列させます。

users_controller.rb
        @graphdays =  @user.sports.order(sport_day: "DESC").limit(6).reverse
        @dayline = Array.new
        @graphdays.each do |graphday|
            @dayline.push(graphday.sport_day.strftime('%m/%d').to_s)
        end

以上、limitの数はご自由に、reverseさせないと表示された時、31日、30日という順番になります。
date型は.to_sを使用しないと文字列として表示されないので注意

Y軸はこちら、時間を配列させます。

users_controller.rb
        graphtimes =  @user.sports.order(sport_day: "DESC").limit(6).reverse
        @timeline = Array.new
        @graphtimes.each do |graphtime|
            @timeline.push(graphtime.sport_time)
        end

こちらもreverseを忘れずに

次はViewです。

show.html.erb
<canvas id="spotsChart" width="200" height="200"></canvas>
   <script>
    var graphdays = <%== @dayline %>, graphtimes = <%= @timeline %>
   </script>
   <script>draw_graph();</script>

ここはvarを使わないと変数が入らないので注意が必要
daylineのところは<%== %>と==が二つならないとなぜか表示されませんでした。
(場合によっては==でなくても大丈夫かも知れません)

最後はcoffeeです。

users.coffee
    window.draw_graph = -> 
    ctx = document.getElementById("sportsChart").getContext('2d')
    sportsChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: graphsdays,#ここは日付が表示される X軸に当たる
            datasets: [{
                label: '運動時間',
                data: graphtimes,#ここは時間が表示される Y軸に当たる
                backgroundColor: [
                    'rgba(255, 159, 64, 0.2)',
                    'rgba(255, 159, 64, 0.2)',
                    'rgba(255, 159, 64, 0.2)',
                    'rgba(255, 159, 64, 0.2)',
                    'rgba(255, 159, 64, 0.2)',
                    'rgba(255, 159, 64, 0.2)'
                ],
                borderColor: [
                    'rgba(255, 159, 64, 1)',
                    'rgba(255, 159, 64, 1)',
                    'rgba(255, 159, 64, 1)',
                    'rgba(255, 159, 64, 1)',
                    'rgba(255, 159, 64, 1)',
                    'rgba(255, 159, 64, 1)'
                ],
                borderWidth: 1
            }]
        },
        options: {
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero:true
                    }
                }]
            }
        }
    })

このようなグラフができると思います。
ダウンロード (1).png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby]Seleniumで開いているページをファイルに保存する

driver.getしたあと、ページを丸ごと保存したいときの情報が見つけられなかったのでメモ。

driver.page_sourceをつかう。

File.open("page1.html", "w") do |file|
  file << driver.page_source
end

参考:7. WebDriver API — Selenium Python Bindings 2 ドキュメント

Seleniumのつかい方は、以下のサイトがとても参考になりました?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

cherry本を通して

cheery本を読んでみて良かったこと

・クラスとモジュールの概念を掴むことができた。
・Procオブジェクトの便利さを再認識
・使えるメソッドの量が増えた

1、ruby内の全てのデータはオブジェクトである。

rubyの全てのデータはオブジェクトだという事は知っていたけど、あまり深くは理解してなかった。オブジェクトは何かしらのクラスに所属している。これを理解することにより、「クラス」というものをより強く意識することができるようになった。「クラス」を意識することにより、役割ごとに処理をまとめることができるようになった。

2、クラスとインスタンス

クラスとインスタンスを意識することにより、クラスメソッドやインスタンスメソッドを意識して使うことができるようになった。インスタンスにどういう属性を持たせるべきか、このインスタンスはクラス内部だけでしか呼ばれないか、もしくは外部でも呼ばれるようにしたいか。(public、private、protected)外部からも呼ばれるようにするためには、アクセサメソッドを定義するなど、一連の流れを掴めるようになった。

3、クラスの継承

今までは、クラスの継承が中々パッと思い浮かばなかったが、コードを各際にまずは何か既存で使えそうなものがないかを考えれるようになった。スーパークラスとサブクラスには明確な関係性があるか、意味の分からない継承をしようとしていないかがわかるようになった。

4、module全般についての知識が高まった。

そもそもmoduleについての知識がものすごく曖昧だった。しかし、moduleがどういう時に使われるのかが明確になった。

モジュールの用途は以下のような時である。
・継承を使わずにクラスにインスタンスメソッドを追加する、もしくは上書きする(include、prependなど)
・複数のクラスに対して共通の特異メソッド(クラスメソッド)を追加する。(extend)
・クラス名や定数名の衝突を防ぐために名前空間を作る。
・関数的メソッドを定義する。
・シングルトンオブジェクトのように扱って設定値などを保持する。

5、Procオブジェクトの便利さを再認識

今まではProcオブジェクトの名前を知っているぐらいで、実際にどう使うかは曖昧だった。procとラムダの違いなんて気にしたこともなかった。チェリー本では、Procについての情報量が多かったので、しっかりと使い方を学ぶことができた。

sample.rb
# ブロック処理ができるラムダの作成はとても簡単
add_lambda = ->(a, b) { a + b }
add_lambda.call(10, 20)  # => 30

6、使えるメソッドが増えた

cherry本の中で色々なメソッドが出てくるので、コード書き写してく時に自然と使い方を学べるのはとてもgoodでした。
例:inject, rjust, scan, values_at, chars, split, with_indexなどなど。

 良かったこと総括

rubyの中での概念、処理の流れなどを理解することができたことが一番良かった。メソッドの探索方法や例外処理が発生した時の処理の手順やクラスの継承など。こういう概念の部分は一見すぐには役立ちそうではないけど、プログラミングをしていく上でこういった概念を理解しているか、いないかで頭の中の整理のされ方が変わってくると思うので、概念を理解することを意識してcherry本を読むことがすごい大事なことだったと思う。あと、ちょくちょく出てくる例題問題は実際に手を動かして、何も見ずに解けるようにするだけでただ本を読むよりかは、何か得られるものがあると思う。

cherry本を読んでも分からないこと。解決できなかったこと。課題。

・1つ1つの概念やメソッドの使い方を理解できたが、暗記したわけではないので、パッと使うことができない。誰かに指摘された時に、あー、そのメソッドを使えばいいのか!というレベル。数あるメソッドの中から、このメソッドをこのタイミングで使う!という絶妙な使い方はやはり仕事の業務をする上で覚えていく感じになるのだと思う。

・言葉では理解できていても、実際に手取り足取り使えるようにはならない。業務を通して、レビューを受けて、徐々に脳に浸透させていくしかないかと。それか、「cherry本」の内容を踏まえて、簡単なプログラムを自分で作ってみるとか。

・どこまで深掘りすべきなのか。

・これは個人的に苦手だなと感じたところだが、「演算子を独自に再定義する」的なことがあまり理解できていないので、もうちょっと調べる必要がある。例えば、comparableモジュールの<=>の再定義とか

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#Ruby 初心者向け問題 | クラスメソッドとインタンスメソッドを組み合わせてメソッドチェーンして遊ぶ

Ruby for beginners | Playing a method chain combining class methods and instance methods

次のクラスを使って OK! と表示させてください

class Story
 def initialize(to: false)
   @to = to
 end

 def be
   @be = true
   self
 end

 def continued
   puts 'OK!' if @to && @be
 end

 def self.to
   new(to: true)
 end
end

Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2366

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rubyで継承した親クラスのメソッドを[super]以外の方法で呼び出したい

問題

  1. 親クラスに子クラスで使う共通のメソッドがある
  2. 子クラスで同名のメソッドがあるが、その場合はsuperで呼べる
  3. 子クラスで全く別のメソッドから、親クラスの特定のメソッドを呼ぶ時はsuperは使えない

下の例で

  def another_method_name
    p "another_method_nameからの呼び出し"
    method_name # => これは自分自身のmethod_nameになる
  end

としたい所だが、C自身のmethod_nameを呼ぶ事になり、paramsなどが違う場合などはC#method_name経由でP#method_nameを呼ぶわけにはいかない。

# another_method_nameメソッドからはPのインスタンスメソッドとなる
# method_nameが直接呼べない。

class P
  def method_name
    p "from parent"
  end
end

class C < P
  def method_name(caller_name)
    p "calling from #{caller_name}"
    # => Pの同名メソッドが呼べる 
    # ()無しだとparamsも全部渡してしまうので、()付でparams無し
    super() 
  end

  def another_method_name
    p "another_method_nameからの呼び出し"

    # 単純に
    # method_name 
    # としてしまうと、自分自身(C)のmethod_nameを呼ぶ事になる
    # superでは自身のメソッドの親側のメソッドを呼ぶため、method_nameではない

    # P#method_nameは直接アクセスできない 
    # なので、Pクラスからmethod_nameメソッドを取り出して動的に呼ぶ
    P.instance_method(:method_name).bind(self).call
  end
end

解決方法

P.instance_method(:method_name).bind(self).call

# または動的にするなら
self.class.ancestors[1].instance_method(:method_name).bind(self).call

# 親のメソッドにparamsがあれば.call(...)で呼ぶ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【速報】Ruby 2.7 の Numbered parameters が @1 から _1 に変更され、pipeline 演算子が見送りになった

ブログ記事からの転載です。

Numbered parameters の記号が @1 から _1 へ変更へ

表題通りなんですが Ruby 2.7 で導入予定であった Numbered parameters の記号が @1 から _1 へと変更になりました。

After discussion and consideration, we picked 1, _2... as numbered parameters. I investigated replaced examples, the current @1 etc. are too confusing with instance variables. So I picked underscore for numbered parameters (a la Scala). We didn't choose Scala's default parameter (), because it is confusing from my view.

The whole parameter (e.g. |a|) can be captured using _0. The _0 part is kind of compromise, but I think it's acceptable.

The bare _1 etc. in the current code will be warned. You can use those identifiers as local variable names or method names, but they are not recommended from 2.7 and later. And they might be prohibited in the future.

Matz.

と、言う感じに matz の意向により Numbered paramters が @1 から _1 へと変更(予定)となりました。
個人的にはまあ〜〜〜〜 it よりはマシなんだけど〜〜〜既存のコードに対して破壊的変更になるのがな〜〜〜やっぱり嫌だな〜〜〜〜。
っていう気持ち。
ぶっちゃけ自作 gem で _1 とか使っているのでホントやめてほしい破壊的変更やめろ!!!!
まあでも matz がいうならしょうがないかなあ〜〜〜〜〜〜という気持ちしかないにゃんねえ…。
少なくとも Numbered parameters 自体が削除されるよりは…。
細かい挙動とか @1 と差異があるのでそのうちまとめたい。

pipeline 演算子がお蔵入り

Ruby 2.7 で pipeline 演算子が導入される予定だったんですが、いろいろとあり Ruby 2.7 に入ることは断念されました。

After experiments, |> have caused more confusion and controversy far more than I expected. I still value the chaining operator, but drawbacks are bigger than the benefit. So I just give up the idea now. Maybe we would revisit the idea in the future (with different operator appearance).

During the discussion, we introduced the comment in the method chain allowed. It will not be removed.

Matz.

pipeline 演算子に関してはこちらを参照。
まあ〜〜〜これも機能としてはほしいので pipeline 演算子ではなくて全然別の機能として復活してほしい気持ちですねえ。
果たして Ruby 2.7 は最終的にどうなるのか…。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】payjpを使用した決済機能を実装する①〜クレジットカードの登録編〜

はじめに

payjpを使用して、クレジットカードにて商品を購入する機能を実装します。
本記事は第一弾として、クレジットカードの登録機能の実装を解説します。
色々と同じような記事もありますが、とりあえず自分用メモです。
JavaScriptを使用して決済する方法もあるのですがこの記事ではRailsのみで実装しています。
誤りやもっと詳細に記載してほしい箇所があればできる限り修正したいので気軽にコメントいただければと思います。

やりたいこと

 ・payjpを使用したクレジットカードの登録機能を実装したい
qiita.gif

全体の流れ

  1. PAYJPにアカウント登録(APIキーの取得)
  2. payjp用のgemを導入
  3. テスト用のシークレットキーをcredentials.yml.encに追加
  4. PAYJPよりトークンを取得し、クレジットカード情報をpayjpに登録する
  5. おまけ(DBへカード情報を登録する)

実装してみる

1. PAYJPにアカウント登録(APIキーの取得)

 PAYJPのアカウントを作成し、APIキーを取得します。
以下は登録後の画面です。画面左側にある、「API」をクリックするとテスト用、本番用の鍵が表示されます。今回は実際に取引を行いたいわけではないので、テスト用のキーを使用します。(3・4章で使用します)
実際にお金のやり取りをしたい場合は、本番用のキーを使用してください。
image.png

2. payjp用のgemを導入

gemfileに以下を記載します。

Gemfile.
gem 'payjp'

bundle installを忘れずに。

ターミナルで実行.
bundle install

3.テスト用のシークレットキーをcredentials.yml.encに追加

4章にて使用したいので、事前準備として「credentials.yml.enc」に以下の通り「テスト秘密鍵」を登録しておきます。

ターミナルで実行(編集用コマンド).
EDITOR="vi" bin/rails credentials:edit
credentials.yml.enc
payjp:
 PAYJP_SECRET_KEY: sk_test_シークレットキーやで

参考:テスト用秘密鍵とは、1章で確認した「sk_test〜」から始まる鍵です。
image.png

4. PAYJPよりトークンを取得し、クレジットカード情報をpayjpに登録する

さて、準備が終わったので実装に入ります。
結論から言うと、クレジットカードの登録機能のコードは以下の通りです。

tbl_card.rb
class TblCard < ApplicationRecord

  require 'payjp'
  Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)

  def self.create_card_to_payjp(params)
    # トークンを作成 
    token = Payjp::Token.create({
      card: {
        number:     params['number'],
        cvc:        params['cvc'],
        exp_month:  params['valid_month'],
        exp_year:   params['valid_year']
      }},
      {'X-Payjp-Direct-Token-Generate': 'true'} 
    )
    # 上記で作成したトークンをもとに顧客情報を作成
    Payjp::Customer.create(card: token.id)
  end
end

一つずつ処理を見ていきます。

①payjpを使用できるようにロードする。

PAYJPとやり取りするために、以下の1行目でpayjpをロードし、2行目で秘密鍵を設定しています。
なお、「:PAYJP_SECRET_KEY」というのは、前章でcredentials.yml.encに設定したものを使用します。
「Payjp.api_key = sk_〜」のように直書きしても処理自体は動くかと思いますが、セキュリティを考えるとcredentials.yml.encに記載するのが良いかと思います。

tbl_card.rb
require 'payjp'
  Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)

②トークンを作成する

PayjpのAPIリファレンスで言うと、「トークンを作成」という項目に当たります。
なお、当章の冒頭で記載したコードでは、各パラメーターをparams['number']のようにviewから受け取った値を使用するように記載していましたが、説明の便宜上、以下では具体的な値を記載します。

tbl_card.rb
    # トークンを作成 
    token = Payjp::Token.create({
      card: {
        number:     '4242424242424242',  # ここが冒頭とは値が違います
        cvc:        '123',               # ここが冒頭とは値が違います
        exp_month:  '2',                 # ここが冒頭とは値が違います
        exp_year:   '2020'               # ここが冒頭とは値が違います
      }},
      {'X-Payjp-Direct-Token-Generate': 'true'} 
    )

ちなみに、、、(例ですが)上記を実行後のレスポンスとして、json形式で以下が返ってきます。(上記でいうと、変数「token」に以下の情報が格納されます)

上記のレスポンス.json
{
  "card": {
    "address_city": null,
    "address_line1": null,
    "address_line2": null,
    "address_state": null,
    "address_zip": null,
    "address_zip_check": "unchecked",
    "brand": "Visa",
    "country": null,
    "created": 1442290383,
    "customer": null,
    "cvc_check": "passed",
    "exp_month": 2,
    "exp_year": 2020,
    "fingerprint": "e1d8225886e3a7211127df751c86787f",
    "id": "car_e3ccd4e0959f45e7c75bacc4be90",
    "livemode": false,
    "metadata": {},
    "last4": "4242",
    "name": null,
    "object": "card"
  },
  "created": 1442290383,
  "id": "tok_5ca06b51685e001723a2c3b4aeb4",    # これがトークンID!!!!!!
  "livemode": false,
  "object": "token",
  "used": false
}

③顧客情報(クレジットカード情報)を登録する。

PayjpのAPIリファレンスで言うと、「顧客を作成」という項目に当たります。
これにより、トークンIDに紐付いた顧客情報が登録できます。
パラメーターは、上記②で取得したトークンID(# これがトークンID!!!!!!と記載したやつ)を渡してやります。なお、取得したレスポンスは変数「token」に格納されていますので、「token.id」とすればトークンIDを取得できますね。

tbl_card.rb
    # 顧客情報(クレジットカード情報)を作成
    Payjp::Customer.create(card: token.id)

ここまでできると、以下のようにPAYJPのダッシュボードにて顧客情報が登録できていることが確認できます。
image.png

5. おまけ(DBへカード情報を登録する)

今回は以下のようにカード情報を表示したいので、

 ・カードのブランド

 ・カードの最後4桁

 ・有効期限(月)

 ・有効期限(年)

をDBへ登録します。
image.png

第4章にて登録した「顧客情報」の実行結果から上記の値を取得します。
今回は中身を確認するために、一時的に変数「test」に実行結果を格納してみます。
中身を確認してみるとこんな感じ。
image.png

以上でクレジットカード情報をPAYJPへ登録ができました。

最後に

 今回はクレジットカードの情報をPAYJPへ登録しました。次回はクレジットカードを使用した商品購入機能の実装をしていきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby]aaaaコロンスペースコロンbbbb という呪文について語る

はじめに

私は現在 Rails を使ったWEBアプリケーションの開発に携わっていますが、ずっと Rails を使っていたわけではありません。以前は PHP や ASP.net を使ってました。

そんな私が Rails での開発を行うようになり、当然言語は Ruby を使うわけですが、Ruby をまったく知らなかった私がまず最初に面食らったのが下記のような記述です。

{ aaaa: :bbbb }

aaaaコロンスペースコロンbbbb?なにこれ? というのが当時の第一印象でした。
当時の私の気持ちをわかりやすく表現するとこんなかんじです。
qb2.png

というわけで今日は私が aaaaコロンスペースコロンbbbb が何かを理解するまでの過程を記事に残してみたいとおもいます。

: : という演算子ではないです

お恥ずかしながら、真っ先にイメージしたのは Ruby には : : という演算子があるのか です。
なので私には一番はじめはこう見えてました。

{ aaaaという変数(?) : :というよくわからない演算子(?) bbbbという変数(?) }

演算子式 (Ruby 2.6.0)

もちろんですがそんな演算子はどこにもありませんでした\(^o^)/

これは Hash らしい

そんな折、{ aaaa: :bbbb } は Hash ですよ と同僚から声をかけられました。大きなヒントは得られたので、Hash のリファレンスを見てみることにしました。

class Hash (Ruby 2.6.0)

ハッシュテーブル(連想配列とも呼ぶ)のクラスです。ハッシュは任意の種類のオブ ジェクト(キー)から任意の種類のオブジェクト(値)への関連づけを行うことができます。

ハッシュ生成は多くの場合以下のようなリテラル (リテラル/ハッシュ式) で行われます。

{ a => b, ... }   # aはキー、bは値となる
{ s: b, ... }    # { :s => b, ... } と同じ。キーがシンボルの場合の省略した書き方
{ "a+": b, ... } # { :"a+" => b, ... } と同じ。上の表現に空白や記号を含めたい場合

連想配列、辞書といえば他言語の経験があれば理解は容易です。もし連想配列という言葉にピンとこない方は こちら をどうぞ。

で、話はリファレンスに戻ります。答えはこの1文です。

{ s: b , ... } # { :s => b, ... } と同じ。キーがシンボルの場合の省略した書き方

Hash の基本は { key => value } ですが、key がシンボルの場合に限りkey: と書くことができる ようです。逆に言えば、key: と書いてあれば key は必ずシンボルであるとも言えますね。シンボルという単語に謎は残るものの、要はこれは連想配列なんだ というざっくりとしたイメージは持てました。

つまり先ほどの例を用いると、aaaa::aaaa => は同義である、ということがわかりました。aaaa: は連想配列のキーなんですね。紛らわしい、なんでコロンの位置が先頭からケツに移動してるんだよ、わかりづらい(言いがかり)

ということでこれで左半分の疑問はほぼ解消できました。

シンボルリテラル

さて、残った疑問です。左側にコロンのついた :aaaa:bbbb というのはいったいなんじゃい?という新たな疑問に悩まされることとなりました。さきほどのハッシュの説明から、:aaaa:bbbb もシンボルというものであるということはわかりました。というわけで続けてリファレンスマニュアルを見てみます。

class Symbol (Ruby 2.6.0)

Symbol って名前の型があるということはわかりました。(浅い)
続けてもう少し見てみましょう。

シンボルオブジェクトは以下のようなリテラルで得られます。

:symbol
:'symbol'
%s!symbol! # %記法

お、:aaaa とか :bbbb と同じ書き方の話が出てきました。

ちなみにリテラルというのはこちらをどうぞ。

リテラル (literal)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

人間語で書いたプログラムの元ネタ(ソースコード)の中に直接べた書きした文字とか数字とかのこと

べた書きというのは例えば 'bbbb' のような書き方です。これは文字列であることは言うまでもないでしょう。この例のようにべた書きされた文字列を 文字列リテラル と呼ぶこともあります。

つまりこういうことですね。

# ベタ書き文字列
'aaaa'
"aaaa"

# ベタ書きシンボル
:bbbb

コロンbbbb の正体はべた書きされたシンボルだったというわけです。数値や文字列以外にもべた書きできるデータがある ということを知らなかった私の世界は狭かったようです。

結論

hash = { aaaa: :bbbb }

  ↓↓ つまり

hash = { ベタ書きされたSymbol型の値 aaaa => ベタ書きされたSymbol型の値 bbbb }

aaaaコロンスペースコロンbbbbとは、Symbol型のキーと値を持つ連想配列であった ということで私は理解しました。

ところで数字でも文字列でもない Symbol ってどういう型?

※コメントを受けて一部文章を修正しました。

この 非常に言葉で説明しづらいテーマ をすごくわかりやすく説明した先人様の記事があったのでこちらをご参考ください。(他力本願)
Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい - Qiita

文字列の皮を被った数値。コード上は文字列で見えてるけど内部では数値として扱われる。

リファレンスマニュアルの説明もわかりやすいです。
https://docs.ruby-lang.org/ja/latest/class/Symbol.html

シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。

名前を管理するという役割上、シンボルと文字列は一対一に対応します。 また、文字列と違い、immutable (変更不可)であり、同値ならば必ず同一です。

文字列のように書けるけど、内部の振舞いが整数のようになります。つまり同じ名前のシンボルは必ず同じオブジェクトを指すようになります、ということでしょうかね。

おわりに

Ruby のハッシュの記法に触れた記事はもうすでにたくさんありますが、そもそも私のように : : が演算子と思いこんだり、コロンスペースコロンってなんだ?と思いこんだ人はハッシュの説明に辿りつけない人も(もしかしたら)いるかもしれない、と思ったのでRubyをはじめてさわった当時(とはいっても1年ちょい前くらい)のことを思い出し、あの頃思ったことをなるべくそのままの言葉で記事にしてみました。どこかの誰か一人だけにでもお役に立てればうれしいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む