- 投稿日:2020-10-26T23:41:17+09:00
[Rails] [メモ] <% %>に=をつける時とつけない時
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
ヘルパーメソッドをビューファイルで記述する時、ふとした瞬間に<% %>の=をつけるかつけないかで間違ってしまうので、忘備録として書きました。<% %>の場合
- ビューファイルで出力させたくない時に使います。
- 例えば、if文などの条件分岐やeach文の繰り返し処理の時などです。
#if文 <% if @name == 'hoge' %> <% end %> #each文 <% @books.each do |book| %> <% end %><%= %>の場合
- ビューファイルで記述した処理を出力させたい時に使います。
<%= book.title %> <%=form_with model: @user, url: user_registration_path, class: 'registration-main', local: true do |f| %> <% end %> <%= f.label :email %> <%= render 'shared/error_messages' %>まとめ
ざっとまとめると<%= %>方が圧倒的に多いですね。
要するに、ifなどの条件分岐やeachのような繰り返し処理は=をつけないで、その他の画面に出力する処理はつけても良いということです。
- 投稿日:2020-10-26T22:46:44+09:00
Rails で検索機能を作ろう(ransack)
はじめに
今回は
ransack
というgemを使って検索機能を作っていきます。ransackは少ないコードで複雑な検索機能を簡単に作れるgemでとても便利です。また、ransackではソート機能も簡単に作れるのでそれも含めて作成していきます。基本的な検索結果の実装
今回検索の対象とするのは、ストレッチ(stretchsテーブル)一覧と、そのカテゴリ(categoriesテーブル)一覧とします。
ストレッチ一覧画面(indexビュー)に検索窓を設けます。gemをインストール
gem 'ransack';
bundle install
でインストールビュー
ストレッチのindexビューに検索窓をつける
<div class= serch.id> <%= search_form_for @q, class:'form-inline' ,url: stretchs_path do |f| %> <%= f.search_field :action_muscles_or_name_cont, class: 'form-control input-lg', placeholder: "ストレッチ名や筋肉名を入力" ,data: {"turbolinks" => false}%> <%= f.submit "検索", class: "btn btn-success btn-lg" %> <% end %> </div>cssで調整
.form-inline .form-control { display: inline-block; width: 80%; }コントローラー
class StretchsController < ApplicationController def index # 検索機能(検索ワードをparams[:q]で受け取り@stretchsに入れる) @q = Stretch.all.ransack(params[:q]) @stretchs = @q.result(distinct: true).page(params[:page]) end end検索ワードをparams[:q]で受け取り、検索で該当したデータをそれぞれ@stretchsに入れ、
再びindexビューに返す形です。以上で簡単な検索機能の実装は完了です。
最後に
今回はransackを使って検索機能を作成しました。
間違っていたりするところがあればご教授お願いします。
- 投稿日:2020-10-26T22:23:34+09:00
RailsのActive Storageで、アップロード前に画像を圧縮する
概要
Active StorageでAmazon S3等に画像を保存するような場合に、圧縮してから画像をアップロードする。
- 環境
- Rails 6.0.3.3
- Active Storage、image_processing、libvips
実装
saveする前に、添付画像(
ActionDispatch::Http::UploadedFile
)のtempfile
を圧縮したものに置き換える。モデル
class Event < ApplicationRecord has_many_attached :images endビュー
<div class="form-group"> <%= f.label :images %> <%= f.file_field :images, multiple: true, class: 'form-control-file' %> </div>圧縮&保存
@event.images.each do |image| image.tempfile = ImageProcessing::MiniMagick.source(image.tempfile).resize_to_fit(1280, 1280).call end @event.save
- 投稿日:2020-10-26T21:28:37+09:00
ruby on rails でのアプリの作り方(環境構築はできているものとします)
ターミナルにて、「cd 〜」でアプリ作成したいディレクトリを選択する。
rails _ 6.0.0 _ new (作成したいアプリ名) -d mysqlを入力すると「create 〜」がたくさん出た後に「Webpacker successfully installed」が表示されれば成功です。
rails newはrubyのフレームワークであるrailsがWebアプリケーションに必要なファイル一式を作成してくれるコマンドです。もしエラーが表示された場合は、
「bundle config --delete build.mysql2」
「bundle config --global build.mysql2 --with-opt-dir="$(brew --prefix openssl)"」
「cd ~(作成したアプリ名)」
「bundle install」と順番に入力すれば大丈夫だと思います。cd (作成したアプリ名)を入力すればそのアプリのディレクトリに移動し、ライブラリの追加などを行えます。
その後、VSCodeなどで(作成したアプリ名)のconfig/database.ymlの14行目くらいに「encoding: utf8mb4」と記述されていると思います。
「utf8mb4」の「mb4」を消し、「encoding: utf8」にします。
ターミナルに移動し、rails db:createを入力すると
「Created database '(作成したアプリ名)_development'」
「Created database '(作成したアプリ名)_test'」の二つが表示されていると思います。
rails sと入力した後、webにて「localhost3000」と入力すると「Yay! You’re on Rails!」の下に、地球に乗った世界各国の人たちがいるイラストが表示されていたら成功です。初学者なので間違いなどあればご指摘いただけるとありがたいです。
- 投稿日:2020-10-26T21:17:31+09:00
[プログラミング大全] §5 Rubyでレビュー管理アプリを作る
目的
「プログラミングを学ぼう!!」と意気込んだものの、
プログラミングって難しそうだし、英語も読めないし、PC操作自体苦手だし、
昔に挫折したし、というあなたに向けて、
この記事を読み・PCを動かすだけで「なんだ!プログラミングって面白いじゃん!」
って思ってもらうのが目的です。プログラミング大全というタイトルで連載化していきたいと考えています。
開発環境
- Mac:macOS10.15.7(メインPC)
- ブラウザ:Google Chrome
- テキストエディタ:VSCode(Visual Studio Code)
準備
- デスクトップに「revew.rb」というフォルダを作ります。
- VsVodeを立ち上げて、「⌘+O」でrevew.rbを開く
完成形
まず、今回の完成形ですがターミナル上で以下の内容が確認できることです。
$ ruby review.rb #以下の内容が表示されれば成功です。 ジャンル:漫画 --------------------------- タイトル:ワンピース --------------------------- 感想: 国民的漫画。 毎週の連載が待ち遠しい。 伏線がすごい! ---------------------------バックスラッシュ記法
バックスラッシュ記法とは\(バックスラッシュ)から始まる記法です。
以下の使い方が可能です。
記法 意味 \n 改行 \t タブ \b バックスペース \ \ バックスラッシュ バックスラッシュ記法は""(ダブルコーテーション)の中で記述します!
\nの記述例です。
puts "①日本の都市は東京です。イギリスの首都はロンドンです" puts "②日本の都市は東京です。\nイギリスの首都はロンドンです"ターミナルでは以下の様に確認できます。
①日本の都市は東京です。イギリスの首都はロンドンです ②日本の都市は東京です。 イギリスの首都はロンドンです
では、\nを用いて本格的に実装を進めていきましょう!
STEP1:画面上に文字の表示
putsメソッドを用いて表記
まずは、putsメソッドを使って完成形を表記します。
review.rbputs "ジャンル" + ":" + "漫画" puts "---------------------------" puts "タイトル" + ":" + "ワンピース" puts "---------------------------" puts "感想" + ":\n" puts "国民的漫画。\n\n" puts "毎週の連載が待ち遠しい。\n\n" puts "伏線がすごい!\n" puts "---------------------------"*上記はあくまで記述方法の1つです。
ターミナルで確認します。$ ruby review.rb #以下の様に表記されていれば成功です。 ジャンル:漫画 --------------------------- タイトル:ワンピース --------------------------- 感想: 国民的漫画。 毎週の連載が待ち遠しい。 伏線がすごい! ---------------------------しかし、このソースコードではputsメソッドが大量に使われ非常に見にくいままです。
前回学習した変数を用いて読みやすくしましょう!変数を用いて表記
以下の様に変数を用いて記述していきます。
review.rb#変数 genre = "漫画" title = "ワンピース" review = "国民的漫画。\n\n毎週の連載が待ち遠しい。\n\n伏線がすごい!" line = "---------------------------" puts "ジャンル" + ":" + genre puts line puts "タイトル" + ":" + title puts line puts "感想" + ":\n" puts review puts line*上記はあくまで記述方法の1つです。
式展開を用いて表記
ここまで文字連結は+を使って表記してきましたが、
式展開を使えばより綺麗にまとめることができます。式展開
文字列の中で式を使い、式によって得られる文字列に含めることができます。
書き方は#{式}です。式展開をする場合は""(ダブルコーテーション)を記述することを忘れてはいけません。
式展開の記述例です。
num = "5" city = "東京" puts "3 + 2 の答えは#{num}です" puts "の本の首都は#{city}です"ターミナルでは以下の様に表示されます。
3 + 2 の答えは5です の本の首都は東京です
では、review.rbを書き換えていきましょう!
review.rb#変数 genre = "漫画" title = "ワンピース" review = "国民的漫画。\n\n毎週の連載が待ち遠しい。\n\n伏線がすごい!" line = "---------------------------" puts "ジャンル : #{genre}\n#{line}" puts "タイトル : #{title}\n#{line}" puts "感想: \n#{review}\n#{line}"以上です!
最初のコードと比べかなり簡潔にまとめられました。備考
───────────────────────────────
■著者おすすめの本
───────────────────────────────「プロになるためのWeb技術入門」
「転職の思考法」
「ハイパワーマーケティング」
「嫌われる勇気」
「アウトプット大全」───────────────────────────────
■著者おすすめの映画
───────────────────────────────「マイ・インターン」
「シン・ゴジラ」
「ドラゴンボール超 ブロリー」
「School of Roc」
- 投稿日:2020-10-26T20:38:41+09:00
指定したいURLから直接ルーティングを作成する方法+α
こんばんは
アロハな男、やすのりです!今日はポートフォリオ作成時にルーティングの記述方法について、悪戦苦闘してしまったので同じことで悩まれている方や、自分が忘れた時用の備忘録として書き留めておこうと思います。
長くなりましたので、先に結論だけ載せておきますね。
結論
検索用のボタンを押した際に移動するページのURLを、コントローラーの管理下にしたくない場合は、
config/routes.rbRails.application.routes.draw do get '/:name', to: 'コントローラー名#edit' endで、大丈夫です!!
↓参考ページはこちら
Railsドキュメント ルーティング
【ルーティング設計】1つのアクションで複数のビューを切り替えて表示する方法それじゃあ、下に詳しく書き連ねていきますね。
状況
トップページから『ホテル』と書かれたボタンを押すとホテルカテゴリーの検索ページへ遷移する機能を作成したかったんですが、URLを
localhost:3000/hotel
という形にしたかったので、まずはコントローラーをそれぞれ別に作成してルーティングに記述してみました。config/routes.rbRails.application.routes.draw do resources :hotels, only [:index] endそうすると、
hotels GET /hotels(.:format) hotels#index
というルーティングが作成されました。これだとURLは希望に近い形で実現はできましたが、項目が多くなればなるほど別途コントローラーを作成しないといけません。
と、いうことは呼び出されるコントローラーを変更すればいいんだ!と思い
config/routes.rbRails.application.routes.draw do resources :hotels, only [:index], controller: 'experiences' endこうすれば、アクセスした時に
experiencesコントローラーのindexアクション
が呼び出される様になるので、viewファイルはテンプレートファイル等を利用することで表示することができると思いますが、この場合は何も記述のないhotelsコントローラー
が出来上がってしまいます。
今回は1つで記述していますが、どんどん項目が増えればその分ルーティングの記述も多くなってファイルも増えていってしまいます。どうしたものか...と思っていろいろ調べていると見つけました!!
まずは、URLを指定のものにしたいならconfig/routes.rbRails.application.routes.draw do get '/hotel', to: 'experiences#index' endと記載するだけで大丈夫でした!!
これは、Railsドキュメントのルーティングページに記載がされていました。
しっかりドキュメントを確認することの大切さを改めて実感しました...
さて、これだけでも当初の目標である『URLを
localhost:3000/hotel
にする』というのは完了していますが、今のままだとページが/hotel
だけじゃなく他の項目も増えた時にどんどん記述が増えていってしまいますね。
せっかくなので、こちらも改善しちゃいましょう!!改善後
experiencesコントローラー
にeditアクション
というものを新たに定義してそこに全てのルーティングがいく様にまとめることができるんです!!controllers/experiences_controller.rbclass ExperiencesController < ApplicationController def edit render "/#{params[:name]}" end endconfig/routes.rbRails.application.routes.draw do get '/:name', to: 'experiences#edit' endまた、URLの
/:name
という部分では、リクエストの送信時にparams内のキーに:name
を設定して部分テンプレートのファイル名をバリューとして渡すことで、editアクション
内のrenderメソッド
で該当するビューファイルを表示させています。今回の経験を経て
公式ドキュメントを読むことの大切さや、先人の方が残して下さった文献のありがたみが身に染みます...
これからも何か問題があれば、どんどん調べていきたいと思います!!
(他力本願な感じもするけど大丈夫かな...)
- 投稿日:2020-10-26T18:12:52+09:00
Rails学習 2日目
Ruby on Rails5速習実践ガイド chapter4
4-2-1 データ型
データベースのカラムにはそれぞれデータ型というものが必要になってくる。
データ型というのはその中に入る値を特定の条件付きで指定するものである。
データ型 説明 :boolean 真偽値 :integer 符号付きの整数 :float 浮動小数点数 :string 文字列(短い) :text 文字列(長い) :date 日付 :datetime 日時 それぞれのカラムに上記のデータ型を付け加えることで中に入るデータを区別する
4-2-2 NOT NULL制約
カラムは値のない場合NULLとして値を設定しテーブルとして保存するがNOT NULLを使うことによってカラムには必ず何らかの値が入ることを指定することができる。
・NOT NULL制約のかけかた
NOT NULL制約には2種類のかけ方がある。1つ目がテーブルを作成する時に制約をつける方法。2つ目がテーブルを作成し終わってから制約を付け足したい時の制約をつける方法である。1.テーブルを作成する時に制約をつける方法
テーブルを作成するためのマイグレーションファイルにそのままNOTNULL制約をかけてしまってからdb:migrateしてテーブルを作成する方法db/migrate/XXXXXXXXXX_create_tasks.rbclass CreateTasks < ActionRecord::Migration[5.2] def change create_table :tasks do |t| t.string :name, null: false t.text :description ...nameの部分は何か値がないと困るのでnameの後ろにnullをつける。
その後ろにnull(空白)でもいいならtrue,空白が嫌(NOTNULL)ならfalseをつける2.テーブルを作成し終わってから制約を付け足したい時の制約をつける方法
$ bin/rails g migration ChangeTaskNameNotNullテーブルはもう作ってしまったのでマイグレーションファイルを変更しても意味がない。なので変更用のマイグレーションファイルを作りそこに変更用のコードを書く
db/migrate/XXXXXXXXXXXX_change_tasks_name_not_null.rbclass ChangeTaskNameNotNull < ActionRecord::Migration[5.2] def change change_column_null :tasks, :name, false end endできた変更用マイグレーションファイルにchange_column_null(カラムをnullにchangeする)を使ってタスクを変更する。
change_column_null :タスク名, :カラム名, :trueかfalseか(trueはnull、falseはnotnull),文字列カラムの長さを指定する (changeメソッド と upメソッドdownメソッド)
文字列の長さを指定するには上記の説明である通り、テーブル作成のマイグレーションファイルに情報を追加するか、情報が決まってしまったテーブルに情報追加のためのマイグレーションファイルを作るかのどちらかである。今回は情報が決まってしまったテーブルに情報追加のためのマイグレーションファイルを作る方法を見てみる。
class ChangeTasksNameLimit30 < ActionRecord::Migration[5.2] def up change_column :tasks, :name, :string, :limit: 30 end def down change_column :tasks, name, :string end end今回はchangeメソッドの代わりにupメソッドとdownメソッドが書かれているところに注目する。本来changeメソッドは上のupメソッドとdownメソッドを合わせて作られるメソッドである。なぜ今回changeメソッドを二つに分けたかというと、答えは[change_column]にある。change_columnをchangeメソッドで使うと何かあった時に元に戻せなくなるのだ。バージョンを戻す時には上げたバージョン(upやchange)を見ながらそれと逆の操作をしてバージョンを戻す。しかしchangeメソッドだとそれがうまくいかないのである。
4-2-4 ユニークインデックスを作成する
ユニークインデックスも上記のようにテーブル作成のマイグレーションファイルか追加変更用のマイグレーションファイルに書かれる。
class AddNameIndexToTasks < ActiveRecord::Migration[5.2] def change add_index :task, :name, unique: true end endユニークインデックスをつけると値(この場合はname)の重複が無くなる(被らなくなる)
4-3-6 オリジナルの検証コードを書く (自分でvalidatesを作る)
app/models/task.rbvalidate :validate_name_not_including_commaまず自分で作ったvalidateの名前をvalidateに入れる。
app/models/tasks.rbprivate def validate_name_not_including_comma errors.add(:name,'にカンマを含めることはできません') if name&.include?(',') end自分の作ったvalidateの内容をprivateメソッドのなか(外部からいじられたらダメなので)で定義。
if name&.include?(',') もしカンマがついた名前があると普通に実行するがカンマがない名前になると結果はnilになりエラーが出てしまう。ぼっち演算子ならnilが出てエラーにならずにnilという言葉だけ出てくる。4-5-1 セッション
セッションがあることによってどんなページへ何回とんでも自分が操作しているという状態は保たれる(ログイン状態になる)
session[user_id] = @user.id @user.id = session[user_id]上がセッションに情報を入れる操作。下がセッションの値を取り出す操作になっている。
4-5-2 Userモデルを作る(password-digest)
password-digestを使うとパスワードが暗号化されパスワード漏洩や不正アクセスの心配が無くなる
password-digestを対応させるにはhas_secure_passwordというコードを書くと使えるようになる。app/models/user.rbclass User < ApplicationRecord has_secure_password endモデルにhas_secure_passwordをかく。そうするとpasswordカラムの下にpassword_confimationというカラムができる。これはパスワード確認のために2回入力させるためのやつ。この2つのパスワードがpassword-digestで暗号化された時に一致しているかどうかで判断する。
4-5-8 ログイン情報の取得を簡単にする
User.find_by(id:session[user_id])今セッションしているidを探すというコードのなのでログインをしていればこのコードでログインしているユーザーを特定できる。
これをApplicationControllerのなかでメソッドとして定義してやるとどこのアクション内でもUser.find_by(id:session[user_id])が働き、ログインしているという情報がついてくる。
なので新しくメソッドを作るapp/controllers/application_controller.rbclass ApplicationController < ActionController::Base helper_method :current_user private def current_user @current_user||=User.find_by(id:session[user_id]) if session[:user_id] end end「もし@current_userが機能しているなら@current_userを、そうじゃない場合はもしuser_idがセッションしている状態ならそのセッションしているユーザーの情報を探して、それを変数@current_userとする」という動作をcurrent_userメソッドと定義する。このメソッドは外部から操作されてはいけないのでprivateメソッドのなかに入れる
4-5-9 ログアウト機能を実装する
ログイン状態はreset_sessionでログアウト状態になる
app/controllers/session_controller.rbdef destroy reset_session redirect_to root_url, notice: 'ログアウトしました' endなのでreset_sessionはdestryコントローラーの中に定義する。
4-5-11-1 データベース上でUserとTaskを紐付ける
UserとTaskを紐づける上で重要になってくるのは【1対多】という関係。User一人に対しTaskは複数存在するといった状況のことである。具体的な紐付けについて説明する。
1.まずtaskのユーザー情報のuserカラムがNOTNULLな状態にならなければいけない。
db/migrate/XXXXXXXXXX_AddUserIdToTasks.rbclass AddUserIdToTasks < ActiveRecord::Migration[5.2] def up execute 'DELETE FROM tasks;' add_reference :tasks, user, null: false, index: true end def down remove_reference :tasks, :user, index: true end endremove_reference:カラムの中の制約を付けたい時にreferenceを使う。
remove_reference :tasks, :user, index: true←このデータを
add_reference :tasks, user, null: false, index: true←userがnull:falseのなるように制約を付け加えた。
execute 'DELETE FROM tasks;'←制約をつける前にuserがnull:falseだったデータがあるかもしれない、もしあったらエラーになる。なのでこのコードを使いテーブルにあるデータを全削除した。2.1対多の関係を表すhas_many :tasksとbelongs_toを使って関係性を構築する。
app/models/user.rbhas_many :tasks endapp/models/task.rbbelongs_to :user endデータベース間の関係はモデルが行うのでモデルに記入。
user has many tasks
tasks belongs to user
の関係になるので
userモデルにhas_many :tasks
tasksモデルにbelongs_to :user
を加える。4-5-11-3 ログインしているユーザーのTaskデータの登録
ログインするためのcreateアクションは以下のようになっている
app/controller/tasks_controller.rbdef create @task = Task.new(task_params) ・ ・ ・ ・ ・ private def task_params params.require(:task).permit(:name, :descrition) end endこのままだと@taskで新規タスクは作られるがログイン中のユーザーのタスクだということがわからなくなる。なので上のコードを書き換える
app/controller/tasks_controller.rbdef create @task = current_user.task.new(task_params) ・ ・ ・ ・ ・ private def task_params params.require(:task).permit(:name, :descrition) end endcurrent_userがつくことによって「現在ログイン中の」という意味のtaskになる。
つまり先頭にcurrent_userをつけると何でも「ログイン中の」という意味がついてくる。
例えば
Task.find(params[:id])→指定したidのタスクを取ってくる
current_user.tasks.find(params[:id])→ログイン中の人のタスクの中から指定したタスクを取ってくる。4-8 scopeを活用する
order(created_at: :desc)などはscopeを使うともっとシンプルな名前に変えることができる。
scope :recent, -> {order(created_at: :desc)}このコードでorder(created_at: :desc)はrecentに書き換えることができる。
その他勉強になったこと
task.errors.full_messagestaskのエラー情報が表示される
task.persisted?taskがデータベースへ登録済みかどうか確認できる。
if task.errors.present? ul#errors_explanation -task.errors.hull_messages.each do |message| li= messageerrors.present?でエラーがあるかないかを判断する。
if user&.authenticate(session_params[:password]) private def session_params params.require(:session).permit(:email, :password) end本来はuser(session_params[:password])だがpassword-digestで暗号化した場合は
user&.authenticate(session_params[:password])になる。if current_user.admin?adminでユーザー管理権限を持っているかを確認することができる。そこにcurrent_userが加わり、「ログインしている人はそのユーザーの管理権限を持っているのか?」というif文になる。
@task = current_user.task.order(created_at: :desc)orderは指定した基準で一覧を並び替える操作
今回はcreated_at(作成日時)を基準で並ぶ順番が変わっている
- 投稿日:2020-10-26T16:59:06+09:00
ソフトウェアやパッケージとバージョン管理に関するセンテンス
PATH
PATHとは、「環境変数」と呼ばれるOS用の変数のこと。PATHには、複数の絶対パスの情報が保存されています。
コマンドが入力されたときに、シェルはPATHに記述されたパスのディレクトリ内のファイルを検索します。つまり、PATHに絶対パスを保存してアプリケーションのありかを示せば、どこからコマンドを実行してもアプリケーションのコマンドを打つことができます。# rbenvのパスを通す % echo 'eval "$(rbenv init -)"' >> ~/.zshrc # MySQLのパスを通す % echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.zshrcechoコマンドは、>>に続けてファイル名を指定することで、ファイルに文字を追加できるLinuxコマンドです。.zshrcにrbenvの設定を反映するためのコマンドを記述することで、PATHを通しています。
コマンドとアプリケーションの関係
コマンドが実行されると、シェルがそれを読み取ってOSに指示を出す。
OSに初めから入っていてすぐに動作できるアプリケーションとは別に、後からPCに追加する必要があり、よく利用されるアプリケーションは、コマンドラインツールとしてまとめられています。コマンドラインツール
コマンドで操作するアプリケーションのまとまりです。
コマンドラインツールを導入することで、OSが初めからコマンドで操作できるアプリケーション以外のアプリケーションをPCにインストールできます。Command Line Tools
macOS専用のコマンドラインツールのことです。
macOSでは、元々Linuxコマンドで操作できるアプリケーションや機能を標準搭載しています。Linuxコマンド以外で操作するアプリケーションの多くはCommand Line Toolsのインストールによって、まとめてPCに導入できます。パッケージとバージョンの管理
パッケージ管理
パッケージとは、プログラムや処理をひとまとめにしたもののことです。ライブラリとも言えますが、パッケージは複数のライブラリをまとめていることもあります。
パッケージ管理とは、パッケージやパッケージが持つライブラリなどの依存関係を考慮してインストールやバージョンアップを行う管理のことです。
1つのパッケージを利用したい場合、そのパッケージと依存関係にあるパッケージも合わせてインストールしてくれます。パッケージ管理ツール
Homebrew(macOSのパッケージ管理ツール)
Yarn(JavaScriptのパッケージ管理ツール)パッケージ
Gem(Rubyのパッケージ)
Node.js(サーバーサイドで利用できるJavaScriptのパッケージ)バージョン管理
rbenv(Rubyのバージョン管理ツール)
- 投稿日:2020-10-26T16:11:35+09:00
[ruby + excel] SaveAsでの注意点
rubyではwin32oleを使えばエクセルを操作することができます。
SaveAsのところでエラーが出てしまったので、注意点をメモします。
method_missing: (in OLE method 'saveas')(WIN32OLERuntimeError)みたいなエラーでした。結論
指定したディレクトリに保存する場合
- 絶対パスにする。
- パスの区切りは/ではなく\にする。require 'win32ole' app = WIN32OLE.new('Excel.Application') book = app.workbooks.add out_path = File.expand_path('test.xlsx').gsub('/', '\\') book.saveas filename: out_path book.close savechanges: false app.quitSaveAsで指定するパスについて
- 相対パスではエクセルが持っているローカルが基準になります。
- パスの区切り文字は/ではなく\にしてあげます。
- 名前付き引数はシンボルで指定してあげます。
1. エクセルが持っているカレント
rubyでは相対パスが利用できます。
エクセルでも相対パスが使えますが、「カレント」が指す場所はエクセルで設定されているローカルフォルダになります。
オプションの「規定のローカル ファイルの保存場所」に書かれている場所です。
なので、rubyが実行している場所をカレントとするために絶対パスにしてあげます。out_path = File.expand_path('test.xlsx')2. パスの区切りは/ではなく\で。
rubyのパスでは、階層の区切りに/(スラッシュ)が使われます。
どうやらこのままでは保存できなかったので区切り文字を(バックスラッシュ)に置き換えます。out_path = File.expand_path('test.xlsx').gsub('/', '\\')3. 名前付き引数の指定
名前付き引数はシンボルで指定できます。
VBAでは「:=」を使いますが、下記のように書きます。workbook.saveas filename: pathなぜできるのかは未検証です。引数をハッシュで渡しているから?
余談
rubyの基本のようですが、
p out_pathでは文字列が""で囲まれ、\が\\とエスケープされて表示されます。
(\\じゃなくて、一つにしたい!と、いろいろやって数時間。。)
あくまでもプロンプトの表示の問題で、実際には\はひとつです。puts out_pathとすればよかったのでした。
ruby初心者のため、間違った記述があるかもしれません。
コメント等でご指摘いただければ幸いです。
- 投稿日:2020-10-26T15:27:57+09:00
【Rails】Rake taskでバッチ処理を実装してみた
はじめに
環境
Rails: 5.2.3
Ruby: 2.6.3
MySQL: 5.6.40内容
users
テーブルのquestion_count
カラムが更新されていないバグがあり、 バッチを作成し、一括で正しい値に更新できるようにしました。- 既存のメソッドを使用しているため分かりにくい箇所があるかもしれませんがご容赦ください。
user.rbhas_many :questions, dependent: false has_many :only_questions_visible_to_user, -> { where(question_id: nil).visible_to_user }, class_name: 'Question', dependent: false scope :visible_to_user, -> { where(is_invalid: false).where(deleted: false) } def update_question_count! update!(question_count: count_questions) end private # question_count を更新する時の集計に利用するメソッド # # @return [Integer] def count_questions only_questions_visible_to_user.size endquestion.rbbelongs_to :user, optional: true実装したコード
- ログを出力して途中経過、更新に失敗したもの認識しやすいようにしてみました。
- 一度のみの実行で、以降は必要なくなるため、
one_shot
ディレクトリ配下に置いて実行後に削除します。lib/tasks/one_shot/update_users_question_count.rake# frozen_string_literal: true namespace :user do desc 'Update users_question_count' task update_question_count: :environment do |_task| index = 0 updated_question_counts = 0 user_count = User.count logger = Logger.new($stdout) logger.info 'Start' User.find_each do |user| begin if user.question_count != user.only_questions_visible_to_user.size user.update_question_count! updated_question_counts += 1 end rescue ActiveRecord::RecordInvalid => e logger.info "Failed to update user_id: #{user.id}" logger.info("#{e.class}: #{e.message}") next end index += 1 case index when 4000, 8000, 12_000, 16_000 logger.info "Progress: #{index}/#{user_count}" end end logger.info "Updated User Count: #{updated_user_counts}" logger.info 'Finished' end endバッチ実行
bundle exec rake user:update_question_count
- 投稿日:2020-10-26T13:37:20+09:00
【Ruby on Rails】論理削除(退会機能)
目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina前提
- 【Ruby on Rails】gemのdeviseを使用し、名前とパスワードのみでログインする方法
- 【Ruby on Rails】URLのidをカラム名に変更 この続きでコードを編集していきます。
流れ
1 カラムの追加
2 modelの編集
3 controllerの編集カラムの追加
ターミナル$ rails g migration AddIsValidToUsers is_valid:booleandefault: true, null: falseを追加。
booleanを使用することにより、ture、falseで退会しているかどうかを判断します。
下記の場合は初期値をtrueに設定しますので、退会済みの場合はfalseとなります。db/migrate/xxxxxxxxxxxxx_add_is_valid_to_users.rbclass AddIsValidToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :is_valid, :boolean, default: true, null: false end endターミナル$ rails db:migratecontrollerの編集
退会画面と退会処理のアクションを作成
app/controllers/homes_controller.rbdef unsubscribe @user = User.find_by(name: params[:name]) end def withdraw @user = User.find_by(name: params[:name]) @user.update(is_valid: false) reset_session redirect_to root_path end退会後のログインを阻止する記述。
app/controllers/users/sessions_controller.rbclass Users::SessionsController < Devise::SessionsController before_action :reject_inactive_user, only: [:create] ... def reject_inactive_user @user = User.find_by(name: params[:user][:name]) if @user if @user.valid_password?(params[:user][:password]) && !@user.is_valid redirect_to new_user_session_path end end end endroutesの編集
config/routes.rbget 'unsubscribe/:name' => 'homes#unsubscribe', as: 'confirm_unsubscribe' patch ':id/withdraw/:name' => 'homes#withdraw', as: 'withdraw_user' put 'withdraw/:name' => 'users#withdraw'viewの編集
app/views/homes/unsubscribe.html.erb<div> <h2>本当に退会しますか?</h2> <div> <p>退会する場合は、『退会する』をクリックしてください。</p> </div> <div> <%= link_to '退会しない', mypage_path(@user) %> <%= link_to "退会する", withdraw_user_path(@user), method: :patch %> </div> </div>参考
まとめ
論理削除のメリット、デメリットは色々あると思いますが、
サービスを運営する場合、顧客情報は大切になりますので、
物理削除ではなく、論理削除で退会にしたほうが、
復活の手段にもなるためおすすめです。またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork
- 投稿日:2020-10-26T13:13:23+09:00
Railsで複数画像アップロード機能とその投稿に対して複数画像をスライドできるように実装してみた
1.複数画像アップロード機能を実装
carrierwaveを使用して複数枚の画像をアップロードできるように実装してみた。
carrierwaveとは?
carrierwaveとは、Railsアプリケーションから画像アップロード機能を簡単に実装できるライブラリ。今回は、carrierwave ver2.1.0を使用しました。
どのように使用したか?
まずは、下のGemをインストールする。
自分のアプリ/Gemfile
gem 'carrierwave' gem 'mini_magick'アップローダーを生成する。
rails g upload imageこれにより次のファイルが生成される。このファイル内でカスタマイズしたいときは処理を加える。
app/upload/image_upload.rbなので、自分は下のように設定を行いました。
自分のアプリ/app/upload/image_upload.rb
class ImageUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick process resize_to_fill: [1000, 1000] version :thumb do process resize_to_fit: [223,223] end version :swiper do process resize_to_fit: [400, 400] end version :thumbnil do process resize_to_fit: [100, 100] end storage :file def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end def extension_whitelist %w(jpg jpeg gif png) end endどのように設定を加えていったかというと、、、
include CarrierWave::MiniMagickアップロード時に画像のリサイズを行いたかったので、minimagickをインストール。image_upload.rb生成時にコメントアウトで記載してあるので#を消して処理コードとして記載。minimagickとは、CプログラムであるimagemagickのRubyのインターフェース。これによって、画像リサイズ用のメソッドを使用することが出来る。
下の処理は、アップロードされるとと、1000×1000pxで切り抜きを行い、次にthumbと呼ばれるバージョンが作成され、223×223pxに拡大縮小される。同じように、swiper、thumbnilと呼ばれるバージョンが作成され、各々のバージョンに拡大縮小される。
※ただし、チーム開発によってはあまりバージョンを増やすのは好ましくないとのこと。process resize_to_fill: [1000, 1000] version :thumb do process resize_to_fit: [223,223] end version :swiper do process resize_to_fit: [400, 400] end version :thumbnil do process resize_to_fit: [100, 100] endこれは、画像がアップロードした時に保存される場所である。デフォルト記載されている。「public/uploads/指定したモデル名/指定したモデルのカラム名/モデルID/画像と各バージョンで作成した画像」のように置かれている。変更した場合は、オーバライドして記載すれば良い。
def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" endこれもデフォルトでコメントアウトで記載されているので処理出来るように記載。許可される拡張機能のホワイトリストを指定することが出来る。jpg、jpeg、gif、png以外の拡張子をアップロードするとレコードが無効になる。
def extension_whitelist %w(jpg jpeg gif png) endここまでで設定の説明は終わりにして、次に親となるpostテーブルと子のimageテーブルを作成する。
postとimageでテーブルを分けたのは、複数投稿に対応する為。
posts content
images url post_id $rails g model Post content:text $rails g model Image url:string post:referenceここでつまずいたのが、自分の場合はimageモデル作成の際にjson型を扱ったことです。 もともと、postテーブル内でimageカラムを作成して複数投稿できる仕様にしようと思ったのですが、新しいimageテーブルを作成して保存するよう変更したため、わざわざjson型にしなくても良いということを後になって気づきました。なので、ここで一つのテーブルで複数画像を扱うならjson型にして、一つのオブジェクトレコードに複数画像を扱えるように設計するのもいいと思います。自分の場合は、別のテーブルを作成してjson型のままにしていますが、特に理由がないのならstring型で作成することをお勧めします。
マイグレーションファイルを作成して、データベースを更新する。
$rails db:migrateモデルファイルに以下の記述を加える。
自分のアプリ/app/model/image.rb
class Image < ApplicationRecord belongs_to :post mount_uploader :url, ImageUploader #アップロード機能を使いたいデータにマウントする。 end自分のアプリ/app/mode/post.rb
class Post < ApplicationRecord validates :content, presence: true, length: { maximum: 1000 } has_many :images, dependent: :destroy accepts_nested_attributes_for :images #postを投稿するとimageも同時に投稿できるようになる endここで注意しなければならないのは、accepts_nested_attributes_forを使うときは、ストロングパラメータにimages_attributesカラムを追記しなければならないこと。以下のようになります。
自分のアプリ/app/controller/post_controller.rb
def new @post = Post.new @image = @post.images.build end def create @post = current_user.posts.new(post_params) if @post.save redirect_to posts_path, success: "投稿しました" else flash[:danger] = "投稿に失敗しました" render :new end end private def post_params params.require(:post).permit(:content, images_attributes: [:url]) endこれで複数画像をパラメーターとして渡せるように設定できました。
続いて、viewで画像をどのように複数投稿できるようにするか考えていきます。
ここで、自分は色々ハマまりました。fields_forメソッドでは、第2引数にmultiple: trueを記述することで複数投稿できるとのことですが、うまくいかず、、、。なので別の方法として、javascriptで複数投稿できるように実装しました。この記事がとてもよく書かれていたので参考にさせていただきました。→Qiita この記事の通りに設定すれば、javascriptが起動して、アップロードするたびにプログラムが動いてくれるはずです。2. swiperで1つの投稿に対して複数画像をスライドできるように実装
swiperとは?
ざっくりというと、スライド機能の実装が簡単にできるフレームワーク。
どのように使用したか?
まずは、アプリケーション内でswiperを使えるように設定します。いくつか方法があるのですが、私はyarnを利用して導入しました。こちらの記事のyarnでの導入方法や内容がとても分かりやすかったので参考にさせていただきました。
→Qiitaswiperをyarnで導入します。
$yarn add swiper $yarn install導入できたか確認するには、packege.json を確認してください。もしyarnを導入していないのであれば、下記のコマンドでyarnを導入してください。(macをお使いの場合)
$brew installl yarn導入したら、application.js、application.scssに下記のように記載します。
自分のアプリ/app/assets/stylesheets/application.scss
@import "swiper/swiper-bundle";自分のアプリ/app/assets/javascript/application.js
//= require swiper/swiper-bundle.js //= swiper.jsswiper.jsファイルを作成し、下記のように記述してください。swiperでは、swiperで加えたい種類のスライド方法を自分で記述し作成する必要があります。swiperのデモから自分のお好みのスライド方法を選び、ソースコードから!-- Initialize Swiper --より下のスクリプト内のjsのコードをコピペしてください。スクリプトタグは記載する必要はありません。私の場合は、ページネーション/動的弾丸でのスライドにしたので下記のようになります。このjsファイル名はswiper.jsでなくても構いません。ファイル名を変更したい場合は、applicaion.js内で記載したファイル名も変更してください。デモ
自分のアプリ/app/assets/javascript/swiper.js
var swiper = new Swiper(".swiper-container", { pagination: { el: ".swiper-pagination", dynamicBullets: true, }, });これで準備は整ったので、viewで実際に実装してみます。
ページネーション/動的弾丸での実装例なので他のスライド方法を選んだ方は、ソースコードを確認してください。自分のアプリ/app/views/posts/index.html.slim
.swiper-container.top-carousel .swiper-wrapper(style="transform: translate3d(0px, 0px, 0px)") - @post.images.each do |img| .swiper-slide(style="width: 400px;") = link_to post do = image_tag img.swiper.url, class: "card-img-top" .swiper-pagination ~省略~ = javascript_include_tag "application"ここで大事なのは、= javascript_include_tag "application"を一番最後に記述することです。これを書き忘れるとswiperが起動してくれません。application.html.slimに書くという方法もありますが、自分はswiperを必要とするページの部分だけに記述してます。また、このimg.url.swiper.urlは、carrierwaveで作成したswiperバージョンの画像を呼び出しています。
これで、自分の場合はswiperを実装することができました。
- 投稿日:2020-10-26T12:15:53+09:00
Railsで問い合わせフォームを実装する
RailsでGmailを利用した問い合わせフォームを実装しました。
ルーティングの設定
まず、ルーティングを設定します。
問い合わせフォームのページで問合せ内容を入力→送信したら送信完了ページに遷移するという想定です。config/routes.rbRails.application.routes.draw do resource :contacts, only: [:new, :create] do get "/thanks" => "contacts#thanks" end endモデルの作成
問合せフォームで入力する内容は、お名前、メールアドレス、問合せ内容の3点としました。
$ rails g model contact name:string email:string content:text$ rails db:migrateコントローラの作成
$ rails g controller contactsapp/controller/contacts_controller.rbclass ContactsController < ApplicationController def new @contact = Contact.new end def create @contact = Contact.new(contact_params) if @contact.save ContactMailer.contact_mail(@contact).deliver redirect_to thanks_contacts_path else render :new end end def thanks end private def contact_params params.require(:contact).permit(:name, :email, :content) end endビュー(お問い合わせフォーム)の作成
私が作成したサイトのテイストに合わせて一部ひらがなにしている箇所がございますが気にしないでください。
app/view/contacts/new.html.erb<h3>おといあわせ</h3> <%= form_with(model: @contact, local: true) do |f| %> <%= f.label :name, "おなまえ" %> <%= f.text_field :name %> <%= f.label :email, "メールアドレス" %> <%= f.email_field :email, autocomplete: "email" %> <%= f.label :content, "ないよう" %> <%= f.text_field :content %> <%= f.submit "おくる" %> <% end %>ビュー(送信完了画面)の作成
app/view/contacts/thanks.html.erb<h3>おといあわせ、ありがとうございました。</h3>メーラーの作成
$ rails g mailer ContactMailerメール送信処理を記載
app/model/contact_mailer.rbclass ContactMailer < ApplicationMailer def contact_mail(contact) @contact = contact mail to:"自分のメールアドレス", subject: "お問い合わせ" end endメール文の作成
app/view/contact_mailer/contact_mail.html.erb<p>ユーザーネーム:<%= @contact.name %></p> <p>メールアドレス:<%= @contact.email %></p> <p>お問い合わせ内容:<%= @contact.content %></p>Gmailサーバーの設定
config/environments/development.rbRails.application.configure do config.action_mailer.perform_deliveries = true config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', domain: 'gmail.com', port: 587, user_name: '自分のメールアドレス', password: ENV["GMAIL_KEY"], authentication: 'plain', enable_starttls_auto: true } endパスワードはGitHubに上がってしまわないように、.envファイルに記載することにします。
Gmailキーの設定
アプリケーションディレクトリ直下の.envファイル(ない場合は作成)に以下を記載します。
GMAIL_KEY=パスワードここに入力するパスワードはGoogleアカウントにアクセスし生成したアプリパスワードを入力します。
セキュリティ→Googleへのログインの欄
2段階認証を設定していない方は、まず設定をした上で、アプリパスワードを生成します。
ここで生成したパスワードを入力します。こちらで実装は完了です。
無事、送受信ができました。
- 投稿日:2020-10-26T12:07:52+09:00
Docker × Rails × RSpecで開発環境で’Could not find ’****’ in any of the sources’が出た時の対処方法
【Rails】Docker × Rails × RSpecの開発環境で’Could not find ’****’ in any of the sources’が出た時の対処方法
Gemfilegroup :development, :test do ~ 以下追加 ~ gem 'rspec-rails' gem 'factory_bot_rails' endGemfileを更新したのでdockerコマンドでbundle install実行
$ docker-compose run web bundle exec rails g rspec:installエラーメッセージ
Could not find diff-lcs-1.4.4 in any of the sources Run `bundle install` to install missing gems.色んな記事を参照させてもらって実行してみるもなかなかうまくいかず・・・
解決方法
いろいろググっている内にキャッシュで bundle install が実行されないていない場合がある?という記事を見させていただき、早速実行しました
$ docker-compose build --no-cache実行結果
$ docker-compose run web bundle exec rails g rspec:install Creating app_run ... done Running via Spring preloader in process 64 create .rspec create spec create spec/spec_helper.rb create spec/rails_helper.rb見事クリエイトに成功
原因
docker-compose build しても cache が有効になっていて設定変更が反映されてうまく動作しないことがあるので、開発中にGemfileを更新した時は
$ docker-compose build --no-cacheで実行する方がいいとのことです
まとめ
spring stop関連の記事が多かったため解決するのに時間がかかってしまった点が反省点。でも初学者だからこそこの積み重ねが大事とも感じました
参考
以下の記事参考にさせていただきました!ありがとうございました!
Dockerでコンテナ内にbundle installされない問題の解決法
docker をキャッシュを使わないでビルドする
- 投稿日:2020-10-26T11:30:17+09:00
thinreportsで中国語(韓国語)のPDFを表示したい
カスタムフォントが選択できない
現状フォントは固定で、持ち込みのフォントは指定できない様子。
このまま中国語(韓国語でも)を入れようとすると、PDFの状態で文字化けを起こす。解決方法
Railsであれば、ここにあるようにinitializerをつくってやる。
config/initializers/thinreports.rbThinreports.configure do |config| config.fallback_fonts << Rails.root.join("app/thinreports/NotoSansCJKsc-Regular.ttf").to_s endここで重要なのはttfフォントで、
NOTO
フォントを使う必要がある。
(□表示は英語圏ではTOFUと呼ばれ、もう豆腐表示はうんざり - no more tofu - NOTO らしい 、ついでにtofulearn.com)最初は「CJK」なんだからフォントファイル一個でChineseJapaneseKorean全部表示できるんでしょ?って思ってたけど、どうやら違う。適当にダウンロードしてきたNotoCJKファイルは日本語バージョンだったため引き続き中国語の表示ができなかった(□になる部分がPDFでは空白表示だった)。
よくよく調べるとCJKでも各地域ごとのフォントバージョンがあるらしい。
- Simplified Chinese (SC)
- Traditional Chinese (TC)
- Japanese (JP)
- Korean (KR)
最初に使ってたファイルはよくよく見ると
NotoSansCJKjp-Regular.ttf
だった。なので、NotoSansCJKsc-Regular.ttf
を適当に探してみて、当ててみたらバッチリだった。
- 投稿日:2020-10-26T01:14:51+09:00
Heroku CLI 操作(コマンド)
あくまでもコマンド一覧です。デプロイする時の順番ではないのでご注意
railsアプリケーションをHerokuにデプロイする為、gemファイルに記述
ruby:Gemfile
group :production do
gem 'rails_12factor'
end
rails_12factorは、開発環境ではなく本番環境で使用するGem,productionは本番環境で使用できる様にする為
コマンド一覧
- herokuにログイン
- heroku login --interactive
- Heroku上に公開するためのアプリケーションを作成
- heroku create アプリ名
- アプリケーションが反映されているか
- git config --list | grep heroku
- heroku上でmy sqlの作成(ClearDBアドオン)
- heroku addons:add cleardb
- Ruby on Railsを使う場合は、 MySQLに対応するGemに変更
- heroku_cleardb=
heroku config:get CLEARDB_DATABASE_URL
- 自身のmysqlのバージョンに変更(URL)
- heroku config:set DATABASE_URL=[自身のmysql]${heroku_cleardb:5}
- credentials.yml.encをmaster.keyによって復号し、中身を確認したい時
- EDITOR="vi" bin/rails credentials:edit
- Heroku上で環境変数の設定
- heroku config:set RAILS_MASTER_KEY=
cat config/master.key
- Herokuの環境変数一覧を表示
- heroku config
- herokuにアプリ反映
- git push heroku master
- heroku上でマイグレーションの反映
- heroku run rails db:migrate
- heroku runはheroku上で操作したい時に使用する
- Herokuにデプロイされたアプリケーションの情報を参照したい時
- heroku apps:info
- 投稿日:2020-10-26T00:22:16+09:00
【Rails】deviseのヘルパーメソッド
1.初めに
deviseを導入した際に使える便利なヘルパーメソッドをメモします。
2.ヘルパーメソッド
メソッド 機能 before_action :authenticate_user! ログイン済ユーザーのみにアクセスを許可する current_user 現在ログインしているユーザーを取得する user_signed_in? ユーザーがサインインしているかどうかを判定する user_session ユーザーのセッション情報にアクセスする ※「user」の部分はモデル名になるので、モデル名に応じて「user」部分を書き換えます。
3.before_action :authenticate_user!
ログイン状態によって表示するページを切り替えるメソッドです。
ユーザーがログインしていなければ、そのユーザーをログイン画面に遷移させます。
before_actionで呼び出すことで、アクションを実行する前にログインしていなければログイン画面に遷移させられます。app/controllers/application_controller.rbclass ArticlesController < ApplicationController before_action :authenticate_user! def index end def show end end
- 投稿日:2020-10-26T00:03:07+09:00
コピぺで使える簡易的なスロットマシーン実装
コピぺで使える簡易的なスロットマシーン実装
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>スロットマシーン 1</title> <style> input { width:40px; font-size:30px; text-align:center; } button { width:50px; } .x1 { padding:10px 0; } .x1 div { float:left; width:60px; text-align:center; } </style> <script> window.onload = function() { var a = document.getElementById('a'); var b1 = document.getElementById('b1'); var b2 = document.getElementById('b2'); var b3 = document.getElementById('b3'); var c1 = document.getElementById('c1'); var c2 = document.getElementById('c2'); var c3 = document.getElementById('c3'); var t1 = null; var t2 = null; var t3 = null; function start() { if (t1) { clearInterval(t1); } if (t2) { clearInterval(t2); } if (t3) { clearInterval(t3); } c1.value = Math.floor(Math.random() * 10); c2.value = Math.floor(Math.random() * 10); c3.value = Math.floor(Math.random() * 10); t1 = setInterval(function () { c1.value = (+c1.value + 1) % 10; }, 200); t2 = setInterval(function () { c2.value = (+c2.value + 1) % 10; }, 200); t3 = setInterval(function () { c3.value = (+c3.value + 1) % 10; }, 200); } function stop1() { if (t1) { clearInterval(t1); t1 = null; } check(); } function stop2() { if (t2) { clearInterval(t2); t2 = null; } check(); } function stop3() { if (t3) { clearInterval(t3); t3 = null; } check(); } function check() { if (!t1 && !t2 && !t3) { if (c1.value == c2.value && c1.value == c3.value) { alert('あたり!'); } else { alert('はずれ!'); } } } a.addEventListener('click', start); b1.addEventListener('click', stop1); b2.addEventListener('click', stop2); b3.addEventListener('click', stop3); start(); } </script> </head> <body> <button type="button" id="a">start</button> <div class="x1"> <div> <input type="text" id="c1"> <button type="button" id="b1">stop</button> </div> <div> <input type="text" id="c2"> <button type="button" id="b2">stop</button> </div> <div> <input type="text" id="c3"> <button type="button" id="b3">stop</button> </div> </div> </body> </html>現場からは以上です!
- 投稿日:2020-10-26T00:01:25+09:00
[Rails] form_with の2種類の書き方
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
form_withとは
- 情報を送信するためのヘルパーメソッドです。
- 入力に必要なHTMLを表示してくれます。
- form_withには2つの書き方があります。
- 1つ目は、入力された情報をデータベースに保存する場合、2つ目は入力された情報をデータベースに保存しない場合です。
データベースに保存する時
model:
に続けてモデルクラスのインスタンスを記述します。f.text_field
でテキストボックスを作成します。<%= form_with model: @book, local: true do |f| %> <%= f.text_field :keyword, placeholder: "keyword", class: "search-input"%> <%= f.submit "search", class: "search-btn" %> <% end %>データベースに保存しない時
url:
に続けて情報送信先のパスを記述します。<%= form_with url: search_path, local: true do |f| %> <%= f.text_field :keyword, placeholder: "keyword", class: "search-input"%> <%= f.submit "search", class: "search-btn" %> <% end %>ルーティングでネストしている場合
- 例えばpostコントローラーにcommentコントローラーのルーティングがネストしているとしましょう。
- その場合、コードはこんな感じになります。
- モデルクラスのインスタンスを親クラスと子クラスの順で2つ記述すれば良いのですね。
<%= form_with model: [@post, @comment] do |f| %> <%= f.text_field :comment%> <%= f.submit %> <% end %>参考
https://pikawaka.com/rails/form_with
https://qiita.com/hmmrjn/items/24f3b8eade206ace17e2