■
Software Development Kit
最近の面談
スタートアップ:最近、そ◯ーさんから最新イヤホンのSDKをもらって、いい感じってわかったんで
自分:ふむふむ、SDK、そーいえばSDK、、、ふわっとしか理解してないな
SDKとは
あるシステムに対応したソフトウェアを開発するために必要なプログラムや技術文書などをひとまとめにしたもの
なるほど、なるほど開発に必要な環境とか開発の方法を教えてもらえるんか
SDKには、プログラムに連結して使用するためのライブラリファイル(他のプログラムに何らかの機能を提供するコードの集まり)、APIの仕様を記述した文書ファイルなどが含まれます。
なるほど、だからいい感じとかわかるんか、SDKがあるから開発コストを把握できるんか
■
require と permit の使い方がよく分からない
そもそもセキュリティを高めるための機能
rails5系が出てくる中で、rails4系リリース時で話題になったストロングパラメーターの話をするのは、非常にダサいですが、rails初心者であれば、つまづきがちなrequireとpermitの話をします。
具体的にいうとこれです
def user_params params.require(:user).permit(:name, :email) end
createの際に送られて来たものをparamsで取得 中身はこんな感じです
{ "action" : "create", "user" : { "name" : "aaa", "email" : "bbb" }, "controller" : "users" }
返り値を見ると controller 名や action 名などもパラメータに含まれていることが分かります
params.require( :user ) の中身を確認
{ "name" : "aaa", "email" : "bbb" }
余談ですが、、、
params.require( :controller ) とすれば "users" が取得できます。
params.require( :action ) とすれば "create" が取得できます。
permit メソッドは許可したいパラメータだけをフィルタしてくれます。
■
moduleとは?
メソッドを格納できるものです、メソッドを入れるための箱的なニュアンスで考えてください
module Number def plus(num1, num2) num1 + num2 end end
module モジュール名 メソッド end
moduleの特徴
多重承継
多重承継をするため、rubyは単一承継と呼ばれるクラスを一つしか承継できない仕様になっています。そこでclassを合わせて、モジュールを使用するすることで、擬似的に多重継承を行っているようにコードを書くことができます
処理の種類ごとに分離することができる
例えば「name」メソッドを同じプログラムで二つ用意したくなったとします。 普通に書くと、同じメソッド名のメソッドは定義できません。 しかし以下のようにモジュールで名前空間を分けることで、二つのnameメソッドを定義することができます。
module Dog def name #Dog用のname処理 end end module Cat def name #Cat用のname処理 end end
moduleを使う
module TestModule def Min(x, y) if x < y return x else return y end end def Max(x, y) if x > y return x else return y end end module_function :Min module_function :Max end puts TestModule.Min(1, 5) puts TestModule.Max(1, 5)
モジュール内のメソッドを実行するには、
「module_function :メソッド名」
のように、module_functionでmodule_functionメソッドを使い、メソッドをモジュール関数にすることで呼び出すことができるようになります。
また、モジュールを実行するには「TestModule.Min(1, 5)」のように、
「モジュール名.メソッド名」
と指定する必要があります。
facebook認証
ライブラリのインストール
gem 'omniauth' gem 'omniauth-facebook' gem 'omniauth-twitter'
カラムの追加 OmniAuthではuid(一意のID)とprovider(FacebookやTwitterなど)をカラムとして利用する。
$ rails g migration AddColumnsToUsers uid:string provider:string
Deviseの設定
config/initializers/devise.rb Devise.setup do |config| # ... config.omniauth :facebook, 'App ID', 'App Secret' config.omniauth :twitter, 'API key', 'API secret' end
Userモデルにモジュールを追加
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable
Userモデルにfindメソッドを実装 uidとproviderの組み合わせは一意であり、これによりユーザを取得する。 レコードに存在しない場合は作成する。
app/models/user.rb class User < ActiveRecord::Base # ... def self.find_for_oauth(auth) user = User.where(uid: auth.uid, provider: auth.provider).first unless user user = User.create( uid: auth.uid, provider: auth.provider, email: User.dummy_email(auth), password: Devise.friendly_token[0, 20] ) end user end private def self.dummy_email(auth) "#{auth.uid}-#{auth.provider}@example.com" end end
メールアドレスでの認証も実装している場合、OAuthでの認証時もメールアドレスを保存する必要がある。 ここでは、uidとproviderの組み合わせが一意なことを利用して、self.dummy_emailのように生成している。
Userコントローラにコールバック処理を実装(わからん)
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def facebook callback_from :facebook end def twitter callback_from :twitter end private def callback_from(provider) provider = provider.to_s @user = User.find_for_oauth(request.env['omniauth.auth']) if @user.persisted? flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize) sign_in_and_redirect @user, event: :authentication else session["devise.#{provider}_data"] = request.env['omniauth.auth'] redirect_to new_user_registration_url end end end
ルーティング処理 以下のように、OAuthのコールバック用のルーティングを設定する。
config/routes.rb Rails.application.routes.draw do devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
# ... end
認証用リンクを追加 以下によりリンクが生成される。 これをビューの任意の位置に記述する。
user_omniauth_authorize_path(:facebook) user_omniauth_authorize_path(:twitter)
今、米国のエリートたちがブロックチェーンスタートアップに乗り換えるワケ
記事であるように、未開拓の領域だからこそ、世の中をよくできる、名声を残せるという期待感から多くのエリートたちがこの領域に殴り込みにかかっている。ブロックチェーンの課題が解決されるのも時間の問題。。
キモズムを超えろ!
ミライのつくり方2020―2045 僕がVRに賭けるわけ (星海社新書)の第3章の「全てを支配するキモズム理論」を読んだので、そこで感じたこと書きます。
- 要約
キモズムとは?
キモズムを超えるための条件
- 人々の不便を解消できるかどうか?
- 具体的なラインとして、JKが使いたいと思える(使いやすい、可愛い、便利)こと
- 疑問点
現状、一般の人々にとって便利なものなのか?
- Netflixを中心とした映像をどこでも大画面で見られる
- VRゲームが楽しめる
- 遠隔地の人間と会って会議できる「テレビ電話以上、現実未満」
- 遠隔地の友達と一緒にゲームしながら楽しめる、新しいコミュニケーション装置
C向けディバイスで先頭を走るfacebookはどのようなマーケティングを行なっているのか?
→若者に対して、影響力のある女優を起用して、広告を打っている
VRゴーグルが一般の人に利用されるためには、何が必要なのか?
検討すべき要素、そもそもvrゴーグルと一口に言ってもあまりに種類が多すぎて難しいので、どのようなコンテンツがあったらVRは普及するのか?に置き換えます。
動画コンテンツ
【グローバル(7カ国総合) 回答】
・エンターテイメント(映画・TV):45%
・バーチャルツーリズム(仮想旅行):38%
・科学や自然に関する動画:34%
【日本 回答】
・エンターテイメント(映画・TV):54%
・ニュース:38%
・スポーツ/コンサート:35%
海外であれば、仮想旅行のコンテンツが伸び代を感じますね。
日本であれば、スポーツとか実用的なコンテンツが望まれてます。
- 解決策
VRでできることは、一般の人を便利する域に達している気がする、
以上!!
回答とコメントが時系列順に並んだページを作る
はじめに
今回は、かなり悩まされた複数のテーブルの情報を同じ配列に入れて一つのタイムライン上で表示する方法を解説します。
回答とコメントが一緒に入ったインスタンス配列を作る
gituhubのプルリク画面をイメージして作っています。作成されたのが古い順に並べています。
ポリモーフィック関連
以上のようなイメージを実現するための手段としてポリモーフィック関連という方法を用います。ポリモーフィックとはある一つのモデルが複数のモデルに属しているのを一つのアソシエーションの定義だけで表現します。通常のアソシエーションで表現した際に生じる以下の課題を解決しています。以下はimageがcompanyとuserに属する関係の場合の具体例です。
- 新たにImageが従属するモデルを作った際、Imageのbelongs_toを増やす必要がある(=カラムを追加しないといけない)
- Imageモデルのインスタンスから直接、従属しているモデル(CompanyなのかUseを判別する事ができない。)
コード例
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
class Company < ActiveRecord::Base
has_many :images, as: :imageable
end
class User < ActiveRecord::Base
has_many :images, as: :imageable
end
|
テーブルのカラム例
imageable_typeにはCompanyやUserなどの所属するクラス名がimageable_idにはリレーションしているインスタンスのidが格納されている
#例1:Companyモデルに帰属する複数の画像を取得する company = Company.find(1) company.images #=> [<Image id:1 ..>,<Image id:2 ..>] #例2:Userモデルに帰属する複数の画像を取得する user = User.find(1) user.images #=> [<Image id:3 ..>,<Image id:4 ..>]
例1、例2はhas_many定義により所属する画像を取得しています。通常のアソシエーションとの違いとしては、親であるcompany, もしくはuserのidを保持するカラム(imageable_id,imageable_type)はあるが、それがcompany_idやuser_idといった名前ではない、という点です。
#例3:Imageモデルが帰属するインスタンスを取得する(帰属先が企業の場合) image = Image.find(1) image.imageable #=> <Company id:1 ..> #例4:Imageモデルが帰属するインスタンスを取得する(帰属先がユーザーの場合) image = Image.find(2) image.imageable #=> <User id:1 ..>
例3、例4は、Imageが帰属するインスタンスを取得しています。image.imageableと記述するだけで関連先のインスタンスを取得することができます。ここで重要なのは、Imageクラスのインスタンスがどのモデルに帰属しているかが分からなくも.imageableと記述するだけで関連先のインスタンスを取得できるという点です。
#例5: Companyモデルに帰属するImageクラスのインスタンスを作成する company = Company.create Image.create(imageable_id: company.id,imageable_type: company.class.to_s) #=> INSERT INTO `Images` (`imageable,_id`, `imageable,_type`, `created_at`, `updated_at`) VALUES (1, 'Company', '2015-0x-0x..', '2015-0x-0x..') #例6: Companyモデルに帰属するImageクラスのインスタンスを作成する company = Company.create company.images.create #=> INSERT INTO `Images` (`imageable,_id`, `imageable,_type`, `created_at`, `updated_at`) VALUES (1, 'Company', '2015-0x-0x..', '2015-0x-0x..')
例5と例6は同じ処理を行っており、どちらもimageクラスのインスタンスを生成しています。
回答とコメント用のモデルを作る
では、ポリモーフィック関連を利用して、回答とコメント用のモデルを生成していきます、ここのモデル名はreviewモデルにします。
app/model/answer_commnet_content.rb
class Review < ActiveRecord::Migration def change create_table :reviews do |t| t.integer :content_id t.string :content_type t.integer :question_id t.timestamps end end end
ポリモーフィック関連の定義
app/models/AnswerCommentContent
class Review < ActiveRecord::Base belongs_to :content, polymorphic: true end
app/models/Comment
class Comment < ActiveRecord::Base has_one :review, as: :content, dependent: :destroy
app/models/Answer
class Answer < ActiveRecord::Base has_one :review, as: :content, dependent: :destroy
質問、回答の投稿時にAnswerCpmmentContentsも同時に追加する
ポリモーフィック関連を利用するためには、質問及び回答が投稿された時にReviewを同時に追加する必要があります。
class QuestionsController < ApplicationController def create question = Question.create(create_params) question.review = Review.create(group_id: question.group_id, updated_at: question.updated_at) redirect_to :root and return end
コールバックを利用して部分的に分けるのと良いです。
ビューにインスタンスの配列を渡す
質問の詳細ページで、質問に対する回答とコメントを取得するためには、該当の質問のreviewを取得する必要がある。
class QuestionController < ApplicationController def show review = current_user.question.reviews.includes(:content) @review = reviews.map(&:content) //reviewsからcontentのみ取得する end end
コントローラから渡したインスタンス配列でタイムラインを表示する
ビューはインスタンスの種類によってビューを出し分けたいと思います。
<%= render @reviews %>
renderメソッドにインスタンス配列を渡した時は、インスタンスに応じて部分テンプレートを自動で呼び出し分けてくれます。
つまり、Answerのインスタンスだった場合は、app/views/answers/_answer.html.erbを呼び、Commentのインスタンスだった場合はapp/views/questions/_comment.html.erbを呼び出します。
非常に長い解説になりましたが、非常に便利な機能ですね。絶対使いこなしたい機能であることは間違いない。。。