【Illustrator】写真をフェードアウトする方法
本日は写真をフェードアウトする方法についての記事です。 こちらも何かと使う場面がある技法だと思うので書き留め。
操作手順
①画像を用意 ②画像と同寸の図形を用意 今回はわかりやすいようにピンクの長方形を用意しています。 ③長方形オブジェクトにグラデーションを適用 白黒のグラデーションをかけましょう。 ④ウィンドウ>透明を選択 ⑤2つのオブジェクトを選択、[透明から不透明マスクを作成]を選択 黒い部分が透明に,白い部分が元の写真をそのまま表示しています。
今回は写真をグラデーションする方法を学んでいきました! イラレには他にも通常のグラデーションをする方法や文字に反映させる方法などもあるので、そのあたりも今後学んでいきたいですね。
今回はこちらを参考にさせていただきました。ありがとうございました。 イラレ グラデーションの基礎+絶対知りたい8つの知識…|Udemy メディア
自分に置き換えて [20210329☀️]
2021/03/29 本日のアウトプット。
・今日の積み上げ・
本日の勉強時間 03:15
最終課題、ついにすべての機能にLGTMをいただきました〜!!
なんだかんだで3月以内に終わらせる、という目標をクリアできました。
明日からは追加機能でやっておいた方がいいよ、と言われたAWSの学習と、オリジナルアプリの本格的な構想に移ります。
それと自主学習で学びたいことがたくさんあるので、それもリストアップして順々に学習していきたいと思います。
・雑記・ 今日はライフコーチとの面談がありました! 前回のときにオリアプについて先輩方の制作物を参考にしたいとお願いしたので、今日は発表時のパワポを見せていただきました。 みなさん、ご自身のご経験だったりご趣味だったりに関係した課題解決をされており、非常に参考になりました。 私も作りたいな〜と考えているのがいくつかほわっとしたのが頭の中にあるので、深掘りして自分の今の実力で作れるか、何を学習すればさらに機能を付随できるかなど考えていきたいと思います。
【Rails】アソシエーションでつながった他のテーブルの情報を表示する
実は初めましての機能。 今回制作している最終課題のフリマアプリは、ユーザー情報以外に商品に関して説明や値段を登録する商品情報と、購入した際に送り先の住所等を登録する購入情報のテーブル、それら二つを紐づけるテーブルにそれぞれ分かれています。 今回は、ビューファイルでの情報の表示について、2点記録します。
商品登録のテーブルにある情報を別の所で表示させたい
ビューファイル(購入情報)の記述は以下の通り。
<div class='buy-item-info'> <%= image_tag @item.image, class: 'buy-item-img' %> <div class='buy-item-right-content'> <h2 class='buy-item-text'> <%= @item.name %> </h2> <div class='buy-item-price'> <p class='item-price-text'>¥<%= @item.price %></p> <p class='item-price-sub-text'><%= @item.shipping_fee_status.name %></p> </div> </div> </div>
@item
に商品情報が入っています。
その商品情報を指定するコントローラー(購入情報)は以下の通り。
@item = Item.find(params[:item_id])
今回の肝だな〜と感じるのはparams
のIDの指定。いつも使っていたparams[:id]
を指定してしまうと、記述している場所(今回なら購入情報)のIDを取得してしまいます。
アソシエーションで繋がっていれば、上記のようなIDの指定の仕方が可能です。
紐付きの有無で表示を変える
ビューファイル(商品情報)の記述は以下の通り。
<% if @item.order_item.present? %> <div class='sold-out'> <span>Sold Out!!</span> </div> <% end %>
アソシエーションで繋がっていれば、変数の後にモデルの指定をすることで繋がりの有無が確認できます。
あとは空か否かを判断するメソッドで確認。
関係するメソッドはコチラを参考にさせていただきました。
今回は、紐づきがtrue
のときにSOLDOUTが表示されるようpresent?
メソッドを使用しました。
まとめ
今回はかなり自分本位のまとめになりました…。 完全に自分しかわかりませんね。 見てしまった方にはごめんなさい。 各モデルのアソシエーションがわからなくなってしまったとき等、実装がわからなくなったときにここの記事に戻ろうと思います。
今回、以下の記事を参考にいたしました。ありがとうございました。 ActiveRecord::RecordNotFound in 小説サイトを参考に真似をし練習中に起きたエラーです。 rubyの真偽判定メソッド(nil?/empty?/blank?/present?)を検証してみた結果、興味深いことがわかった
立ち止まり、でも停滞はしない [20210327☀️]
2021/03/26 本日のアウトプット。
・今日の積み上げ・
Rubyドリル
記事作成 2本 05:37
英語学習 00:41
mikan 900
Polyglots 1本
ディクトレ 5本
本日の勉強時間 06:18
今日は購入機能で新しく学んだ機能や、遭遇したエラーの整理とアウトプットをしました。
改めて紙に書き出したりすると理解度が深まる気がします。
その代わりかなり時間がかかってしまいました。
理解度を深めると言う意味では時間をかけてもいいのかもしれませんが、やはりどんどん進めて新しいインプットもしたいのでメリハリをつけて勉強していきたいと思います。
・雑記・
明日はお勉強はいったんお休みです。(単語とかはやりますが)
前々から予約していたビュッフェに行くので楽しみです!
休息をしっかり取って、来週以降頑張れるようにパワーためていきます💥
ちなみにですが…今日食べた汁なし担々麺も美味しかったのでこちらにもあげちゃいます。Twitterには先に載せちゃいましたが。
へへ。
【Rails】Formオブジェクトパターンでの実装
複数のモデルのデータ定義の生成・更新で用いるFormオブジェクトパターン。 デザインパターン(実現したいゴールに対して最適な方法や手順をまとめたもの)の一つです。 アプリの商品購入機能において、こちらのパターンを使用して実装を行ったので、ここに備忘録を残しておきます。 ここの箇所、エラーがたくさん出て試行錯誤を繰り返した内容でもあります。 実装手順とともに、遭遇したエラーも記載して、内容の理解をさらに深めようと思います。
なぜFormオブジェクトパターンを使うのか?
今まで通り、一つのコントローラーの中にそれぞれのモデルに対してparams
を定義し、それをcreate
していけばいいのではないか。
そうすると、もし入力を間違った場合(バリデーションに引っかかった場合)に保存ができません。
実装の手順
①modelsディレクトリ直下にFormオブジェクト用のファイルを生成する
②生成したファイル内に、以下の記述を行う
class Order include ActiveModel::Model //①~ attr_accessor :post_code, :prefecture_id, :city, :address, :building, :phone_number, :user_id, :item_id,:token //~① with_options presence: true do //②~ validates :post_code, format: {with: /\A[0-9]{3}-[0-9]{4}\z/, message: "例)123-4567"} validates :prefecture_id, numericality: {other_than: 0, message: "can't be blank"} validates :city validates :address validates :phone_number, format: {with: /\d{10,11}/}, length: {maximum: 11} validates :token validates :user_id validates :item_id end //~② def save //③~ order_item = OrderItem.create(user_id:user_id, item_id:item_id) Deliver.create(post_code:post_code, prefecture_id:prefecture_id, city:city, address:address,building:building,phone_number:phone_number, order_item_id:order_item.id) end //~③ end
include ActiveModel::Model
を用いると、form_withやrenderを使えるようになったり、バリデーションの設定ができるようになります。
attr_accessor
メソッドでゲッターとセッターを定義することで、インスタンスを生成した際にform_withの引数として利用することができる。
def index @order = Order.new end def create @order = Order.new(order_params) if @order.valid? pay_item @order.save return redirect_to root_path else render 'index' end end ~~省略~~ def order_params params.require(:order).permit(:post_code, :prefecture_id, :city, :address, :building, :phone_number).merge(user_id: current_user.id, item_id: params[:item_id], token:params[:token]) end
current_userメソッドはコントローラー内に記述すること。(理由は後述) ④form_withメソッドを用いてインスタンスを渡せるような記述を行う
<%= form_with model: @order, url: item_delivers_path,id: 'charge-form', class: 'transaction-form-wrap',local: true do |f| %> <%= render 'shared/error_messages', model: f.object %> ~~後略~~
以下、ビューファイル記述の際の注意点です。
実装中に遭遇したエラーを紐解く
今回は、住所やクレジットカード情報を保存するdeliverモデルと、商品情報とdeliver情報を紐づけるorder_itemモデルのふたつをFormオブジェクトを用いて保存していきました。
①paramsについて、MissingParamsやNoMethodErrorになる
order_itemのparamsがないと怒られたり、アソシエーションが定義されていないと怒られました。
・原因・ 本来、紐付け用に生成したorder_itemモデルをFormオブジェクトとして使用し、そのなかにバリデーションとアソシエーションを定義していました。
class Order include ActiveModel::Model attr_accessor :post_code, :prefecture_id, :city, :address, :building, :phone_number, :user_id, :item_id,:token with_options presence: true do validates :post_code, format: {with: /\A[0-9]{3}-[0-9]{4}\z/, message: "例)123-4567"} validates :prefecture_id, numericality: {other_than: 0, message: "can't be blank"} validates :city validates :address validates :phone_number, format: {with: /\d{10,11}/}, length: {maximum: 11} validates :token validates :user_id validates :item_id end def save order_item = OrderItem.create(user_id:user_id, item_id:item_id) Deliver.create(post_code:post_code, prefecture_id:prefecture_id, city:city, address:address,building:building,phone_number:phone_number, order_item_id:order_item.id) end belongs_to :user belongs_to :item has_one :deliver extend ActiveHash::Associations::ActiveRecordExtensions belongs_to :prefecture end
今まで定義していたモデルは、すべてApplicationRecordが定義されていたため、バリデーションやアソシエーションが組めていました。
Formオブジェクトは手入力で生成するので、アソシエーションやsaveメソッド、current_userメソッドは使えません。
(バリデーションは、include ActiveModel::Model
を定義しているので使用可能。)
・解決策・
Formオブジェクト内にはバリデーションのみ記述すること。
②値の取得・保存に関するエラー
購入するitemのデータを取得したいのですが、find
メソッドを使っても見つけることができません。
・原因・
params
での値の取得の仕方
def item_find @item = Item.find(params[:id]) end
このままでは、orderモデルのparams
のIDを取得してしまいます。
欲しいのはitemのID。
create
するときの()内の記述
def save order_item = OrderItem.create(user_id:user.id, item_id:item.id) Deliver.create(post_code:post_code, prefecture_id:prefecture_id, city:city, address:address,building:building,phone_number:phone_number, order_item_id:order_item.id) end
ここの部分、ちゃんと理解していなかったのでなんとなくで書いていました。反省。 ・解決策・
params
の記述を以下に変更。
def item_find @item = Item.find(params[:item_id]) end
params
内の[]内は、params
のどこの値を取得するかです。
今回は、紐づいているitemのIDを取得したかったため、params
のmerge
部分に記述されているカラム名を選択しています。
def save order_item = OrderItem.create(user_id:user_id, item_id:item_id) Deliver.create(post_code:post_code, prefecture_id:prefecture_id, city:city, address:address,building:building,phone_number:phone_number, order_item_id:order_item.id) end
そもそもの話ですが…
Xxx.create(name: name,..........,user_id:user_id)
このような記述があった場合、:の左側はテーブルのカラム名、右側はストロングパラメーターやattr_accecorメソッド、ビューなどに入力された値をそれぞれ指します。
ここはなんとなくの私の認識なので間違っていたら訂正をお願いしたいのですが、
user_id→カラム名とかform_with内とかで使用する名前で、値を入れる箱
user.id→値そのもの。これをカラムとかの箱に入れる。
このように認識しています。
今回は、ビューファイル内等すべてuser_id
で記述していたので、create
()内の記述もこれに統一しました。
まとめ
Formオブジェクトを作成していく上では、モデル同士やモデルとコントローラー、ビューなどそれぞれの関係性をきちんと理解していないと記述できないな、と感じました。(だからエラー沼に落ちた…) 流れの把握もそうなのですが、それぞれが値なのか、カラム名なのかという細かいところまで確認しながら実装していかないといけませんね。 最初は時間がかかるかもしれませんが、徐々に慣れていきたいと思います。
【Rails】PAY.JPを用いた購入機能の実装について
購入機能の実装が一段落したので関連する機能およびエラーについてアウトプットしていきたいと思います。 今回はPAY.JPを用いた購入機能の実装について。 ネットでもリアルでもクレジットカードが使えない場面というのは今やほとんどないですよね。(ラーメン屋さんとかは券売機使ってるから現金のみのところも多い気がしますが) スタンダードな決済機能、しっかりと実装していきましょう!
なぜオープンAPIを使うのか?
そもそもの前提の話をまず記録しておきます。 簡単な話、カード会社と直接連携しようとすると発生する以下2点の問題が解決できるからオープンAPIを使用します。
- 会社ごとに事務的手続きをして連携しなければならない
- 金銭の授受に関わるため、一定のセキュリティー基準をクリアしないといけない
尚、カード情報を直接アプリケーションに送ってサーバーにデータを保存・処理を行うことが2018年6月以降、改正割賦販売法によって禁じられています。 したがって、トークン(セキュリティを担保するために用いられる、一回のみ使用可能なパスワード)を使用して処理することで決済をおこないます。
実装の手順
実装の流れとしては、クライアントサイド→クライアントサイド(トークン送付)→サーバーサイド(決済機能)です。
・クライアントサイド実装・ ①turbolinksの確認 今回は手作業でJavaScriptを記述してフォーム送信処理等を実装していくので、turbolinksは使用しません。 そのため、以下2ファイルの記述を確認していきます。
<%# 省略 %> <%= stylesheet_link_tag 'application', media: 'all' %> <%= javascript_pack_tag 'application' %> <%# 省略 %>
require("@rails/ujs").start() require("turbolinks").start() →コメントアウトする require("@rails/activestorage").start() require("channels")
②クライアントサイドでPAY.JPのAPIを使用するために必要なJavaScriptを読み込む ビューファイルに以下の一文を記述し、JavaScriptを読み込ませます。
<head> <title>Furima</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <script type="text/javascript" src="https://js.pay.jp/v1/"></script> //追記 <%= stylesheet_link_tag 'application', media: 'all' %> <%= javascript_pack_tag 'application' %> </head>
③トークン化を行うJavaScriptファイルを作成
app/javascriptディレクトリに直接JavaScriptファイルを生成。
また、application.jsにrequire("xxx")
を記述し、JSファイルが読み込まれるようにします(xxxがファイル名、階層があるときはそれも記述しよう)。
手作業で生成したファイルに、以下を記述。
const pay = () => { Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY); //② const form = document.getElementById("charge-form"); //①~ form.addEventListener("submit", (e) => { e.preventDefault(); //~① const formResult = document.getElementById("charge-form"); //③~ const formData = new FormData(formResult); const card = { number: formData.get("order[number]"), cvc: formData.get("order[cvc]"), exp_month: formData.get("order[exp_month]"), exp_year: `20${formData.get("order[exp_year]")}`, }; //~③ Payjp.createToken(card, (status, response) => { //④~ if (status == 200) { const token = response.id; //~④ } )}; }); }; window.addEventListener("load", pay);
console.log
の記述をおこない、それぞれが正しく機能しているか確認しましょう。
FormDataとは、フォームに記載された値を取得できるオブジェクト。 今回は
charge-form
でフォーム全体を指定し、そこで入力された値をformData
として生成します。
また、card
で各フォームの情報を取得します。
get
以降の()内は各フォームのname属性を指定するのですが、必ず検証ツールから取得しましょう。
exp_year
(有効期限の年の部分)は20xx年になるように記述することも忘れずに!
createToken
の第1引数にcard(取得したカード情報)、第2引数にstatus,responseをアロー関数(functionの代わりに() =>を用いて関数を定義)を用いて定義しています。
status
にはHTTPのステータスコード、response
にはそのレスポンスの内容が入ります。
変数token
にresponse.id
を入れることで、トークンの値を取得できます。
・トークン送付に関するクライアントサイドの実装・ ①トークン情報をフォームに追加・送信
const pay = () => { Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY); const form = document.getElementById("charge-form"); form.addEventListener("submit", (e) => { e.preventDefault(); const formResult = document.getElementById("charge-form"); const formData = new FormData(formResult); const card = { number: formData.get("order[number]"), cvc: formData.get("order[cvc]"), exp_month: formData.get("order[exp_month]"), exp_year: `20${formData.get("order[exp_year]")}`, }; Payjp.createToken(card, (status, response) => { if (status == 200) { const token = response.id; const renderDom = document.getElementById("charge-form"); //①~ const tokenObj = `<input value=${token} name='token' type="hidden">`; renderDom.insertAdjacentHTML("beforeend", tokenObj); } //~① document.getElementById("card-number").removeAttribute("name"); //②~ document.getElementById("card-exp-month").removeAttribute("name"); document.getElementById("card-exp-year").removeAttribute("name"); document.getElementById("card-cvc").removeAttribute("name"); //~② document.getElementById("charge-form").submit(); //③ }); }); }; window.addEventListener("load", pay);
debugger;
で処理を確かめてから、input要素をtype="hidden"
で隠します。
e.preventDefault();
でRailsの送信処理をキャンセルしているため、JavaScriptから送信するような記述を行います。
・サーバーサイドにおける実装・ ①ストロングパラメーターにトークンの情報を追加
def order_params params.require(:order).permit(:post_code, :prefecture_id, :city, :address, :building, :phone_number).merge(user_id: current_user.id, item_id: params[:item_id], token:params[:token]) end
②モデルにトークンの情報を追加
class Order < ApplicationRecord attr_accessor :token ~~省略~~
attr_accessorメソッドとは、記述したクラスにゲッターとセッターを定義してくれるもの。 モデルに対応するテーブルのカラム名以外を扱いたい時に使用する。 ③PAY.JPによる決済処理
def pay_item Payjp.api_key = ENV["PAYJP_SECRET_KEY"] //① Payjp::Charge.create( amount: @item.price, card: order_params[:token], currency: 'jpy' ) //② end
Payjp::Charge.create
というクラス及びクラスメソッドを使用して値段、カード情報、通貨単位の情報を保存する。
④バリデーションの設定 空の情報は送信できないよう設定。
validates :token, presence:true
まとめ
JavaScriptの記述にまだ慣れていないので、とっても難しく感じています どのname属性、IDなどの値を取得するのかなど、一つ一つの処理の意味を考えていけば自ずとわかるはず… なのでまずは流れを確認しながら、繰り返し復習していきたいと思います!
一段落、でも止まらない [20210326☁️]
2021/03/26 本日のアウトプット。
・今日の積み上げ・
本日の勉強時間 02:57
購入機能の実装が終了しました〜〜!!!!!
ここでの機能ははじめましての内容も、また頭に定着していない内容もてんこもりだった気がします。
しっかり復習、まずは今までのエラー等のアウトプットをしていきます。
記事に残していくことで自分の中の資料増やしていくぞ〜〜〜!!
・雑記・ いよいよ最終課題も残るはベーシック認証と追加実装のAWS実装のみ。 オリジナルアプリ制作、追加の自主学習、ポートフォリオサイトの制作とやることがたくさんです。 でも今までより自由度が高いから楽しみです! 自主学習はとにかく基礎固めとしてWebの基礎、Linux、JavaScriptをやっていきたいと思っています。詰め込みすぎなのかな? でもエンジニアとして働いていく上で、ちゃんと自分の中で基盤を構築していきたいと思っているのでしっかりやっていきたいと思います!