- 投稿日:2019-04-11T22:57:49+09:00
[Rails][MySQL] 絵文字を保存できるようにする
「?」みたいな絵文字をMySQLに保存したい。
方法
my.cnf に以下を追記
「/etc/my.cnf」「/etc/mysql/my.cnf」あたりにあるはず。
※最後の3行は、
MariaDB >= 10.3.1ならデフォルトで設定されているので追記しなくてよい。
(設定自体が出来なくなってもいる。 参考:https://github.com/frappe/bench/issues/670))my.cnf[mysql] default-character-set=utf8mb4 [mysqld] character-set-server = utf8mb4 skip-character-set-client-handshake character-set-server = utf8mb4 collation-server = utf8mb4_general_ci init-connect = SET NAMES utf8mb4 innodb_file_format = Barracuda # MariaDB >= 10.3.1 なら削除 innodb_file_per_table = 1 # MariaDB >= 10.3.1 なら削除 innodb_large_prefix # MariaDB >= 10.3.1 なら削除database.ymlを変更
database.ymlencoding: utf8 # 変更前 ↓ encoding: utf8mb4 # 変更後databaseを作成
bashbundle exec rake db:create bundle exec rake db:migrate参考
https://qiita.com/okamu_/items/5eb81688849fbe351350
https://y-hilite.com/3192/
- 投稿日:2019-04-11T22:35:26+09:00
docker-composeでrails開発時のA server is already running. Check xxxx/tmp/pids/server.pid. 対応
docker-compose.ymlversion: '3.7' services: backend: tty: true stdin_open: true build: context: ./backend working_dir: /usr/src/app environment: BUNDLE_JOBS: 4 DB_HOST: db AUTODOC: $AUTODOC command: bin/rails s volumes: - ./backend:/usr/src/app - bundle:/usr/local/bundle - /usr/src/app/.bundle tmpfs: - /usr/src/app/tmp/pidstmpfsに乗っけることで、停止時に消えてくれるはず。
- 投稿日:2019-04-11T22:14:23+09:00
21日目:H30秋基本情報技術者試験の問3データベース
前回のアウトプットから、だいぶ間が空いたが、今回から暫く、基本情報技術者試験問題に向き合う。
コンサートチケットの予約販売サイト、特にチケット販売サブシステムを用いる問題だった。
特に、今回のスクールの大成すべく、問3は実際にDBのみならず、Appも作成したい。
出典: 平成30年度 秋期 基本情報技術者試験(FE)試験区分 午後 問1 問3DB仕様、ER図
販売サブシステムの(引用、一部編集)
- コンサートの席種はS,A,Bがあり、コンサート毎にその価格と発売席数は異なる。
- 取り扱うコンサートの席種(S,A,B)毎の販売可能な席数を管理する。
- 会員が購入申込すると、一意な販売IDを生成して販売表にレコード追加
- 会員が支払いをすると、決済処理として決済表に追加。
- 決済期限の翌日に、決済期限を過ぎた販売表中のレコードと販売IDが同じレコードが決済表にない場合、購入申込は取り消され、バッチ処理として、決済表に当該販売IDを主キーとして決済表に決済日をnull、決済額を-1としてレコード追加
- バッチ処理は毎夜0~4時の販売サイトのシステムメンテナンス時に行う
- 購入申込席数が販売可能な席数を上回る場合は、販売終了と表示し、購入申込を受け付けない 等々。。。
※注意事項
コンサート席種のカラムが、商品詳細表と販売表に1つずつあり、重複していて気持ち悪いが、
試験問題がそうなっており、敢えてそうしてる模様なので、そのままにする。
その意図を反映するため、席種の商品詳細表側はinteger、販売表側はstringにしておく。使用環境
- ホストOS: Windows10 Home
- 仮想環境OS: Ubuntu Bento/Bionic
- Ruby:2.51
- Rails: 5.2.2
- 暫定追加gem : devise
- DB: PostgreSQL
rails gコマ
今回もdeviseを利用することを、頭に入れておきたい。
terminalrails new concert_ticket -d postgesqlGemfile# miniracerをコメントアウト gem 'miniracer' # authentication gem 'devise'terminalbundledatabase.ymlusername: admin password: 〇×△ host: localhostterminalrails db:createterminal# deviseのインストール rails g devise:install # Userモデルにdeviseを追加。モデルなので、単数形 rails g devise User name:string email:string point:integer # 商品表と商品詳細表テーブルはscaffoldを用いる rails g scaffold Concert concert_info:text concert_date:datetime rails g scaffold ConcertDetail concert:references seat_grade:integer seat_price:integer tickets_total:integer # Saleモデルの追加 # カラムが多い。販売表モデル 商品表外部キー 会員表外部キー 席種 席数 販売日 販売額 決済期限日 使用ポイント rails g model Sale concert:references user:references seat_grade:string seats_total:integer sale_date:datetime sales_total:integer payment_deadline:datetime used_point:integer # 決済表モデルを追加 rails g model Payment sale:references payment_date:datetime payment_total:integer added_point:integer関連付け
app/models/concert.rbhas_many :concert_detail has_many :saleapp/models/concert_detail.rbbelongs_to :concertapp/models/user.rbhas_many :saleapp/models/sale.rbhas_one :payment belongs_to :concert belongs_to :userapp/models/payment.rbbelongs_to :saleuserテーブルにadminカラム追加
単に入れ忘れた。
terminalrails g migration AddAdminToUser admin:boolean/db/migrate/(timestanp)_add_admin_to_student.rbclass AddAdminToUser < ActiveRecord::Migration[5.2] def change add_column :students, :admin, :boolean,default: false end endvalidation追加
後からさらに追加していくと思うが、次のデータ入力の為に。
なお、ファイル中のvalidation前後のコードは省略。app/models/user.rb# name の空欄不可 validates :name, presence: true # emailの空欄不可、一意指定 validates :email, presence: true, uniqueness: true # emailの構成文字の大文字小文字の区別はしない # あとで、正規表現込みのvalidation追加等するが、あとまわし。 validates :email, presence: { case_sensitive: false }app/models/sale.rb# 購入席数の空欄不可 validates :seats_total, presence: true # 購入席数は4席まで。(試験問題には無いけど) validates :seats_total, numericality: {less_than_or_equal_to: 4}初期データ作成 (seeds.rb使用)
普段はコンソールからが多いが、rails tutorialをやって、seeds.rbの方が勝手が良かったので。
あと、gem Fakerは、SAOなど『遊び』があって、好きだが、rubyメソッドの勉強にならないので、今回はパスユーザ作成
カラムは氏名とemailアドレス
db/seeds.rb# 管理者 User.create!(name: 'おりばー', email: 'ないしょ@gmail.com', password: 'ないしょ', admin: true) # 一般ユーザ。とりあえず、20人作る。 20.times do |i| nm = (1..5).map { ('あ'..'ん').to_a[rand(20)] }.join em = ('a'..'z').to_a.shuffle[1..5].join User.create!(name: nm, email: "#{em}-#{i}@gmail.com", password: SecureRandom.base64) end商品表と商品詳細表の作成
(まだ足りないと思うが)リファクタリングの結果、コードが合わさったので、纏めて表示。
なお、qiita用に、一部コードの順序を変えてある、が、見づらい。db/seeds.rb# concert # 20回分のコンサート、20組分のアーティストを作成 require 'active_support/all' concert_name = %w[雅楽 令和 ジャズ ラスト ロック アニソン] local = %w[東京 札幌 名古屋 大阪 広島 宮崎 台南 Cebu Perth] artists = [] # 20回分のコンサート、20組分のアーティストを作成 (1..20).each do |n| # コンサート開催日として、期間s1 ~ s2までのランダムな年月日を作成 s1 = Date.new(2019,5,31) s2 = Date.new(2020,3,31) s = Random.rand(s1..s2) # 出演アーティストをランダムで作成して、配列に入れる。 # 作成した配列の並びをシャッフルし、先頭から1~5アーティストを取得し、カンマで繋げた文字列に。 artists << (1..3).map { ('A'..'Z').to_a[rand(20)] }.join.to_s who_join = artists.shuffle.take(rand(5)+1).join('、') # 試験問題の"クリスマスコンサート2018 in 東京 出演:Xバンド・・・"の表記に沿ってあげる。 infomation = "#{concert_name.sample}コンサート #{s.strftime('%Y')} in #{local.sample} 出演:#{who_join}" # コンサート情報の開催年と、開催日時が合致するようにした。 Concert.create!(concert_info: infomation, concert_date: s.strftime('%Y-%-m-%-d')) con = Concert.find(n) (0..2).each do |i| # seat_price S > A > B # prices = [price_s , price_a , price_b] # capa= [sの席数、aの席数、bの席数] prices = [[40000, 35000, 30000], [28000, 25000, 23000, 19000], [18000, 15000, 13000, 11000, 9000]] capa = [rand(10..50), rand(100..500), rand(500..1000)] ConcertDetail.create!(concert:con,seat_grade:i, seat_price:prices[i].sample, tickets_total: capa[i-1]) end endactrive_recordを使おう
初期データ投入
terminalralis db:seedカラム名を変更しよう
思った。非常に分かりづらい。controller作成時に疲れそう。
会員表(User)テーブルはパス。あと、コードは一部省略商品表(Concert)テーブル
現状カラム:コンサート情報:concert_info , 開催日時:concert_date
=>infomation , datedb/migrate/(timestanp)_create_concerts.rbcreate_table :concerts do |t| t.text :infomation t.datetime :date t.timestamps end商品詳細表(ConcertDetail)テーブル
現状:席種:seat_grade , 販売価格:seat_price , 販売席数:ticket_total
=> grade , price , capacitydb/migrate/(timestanp)_create_concert_details.rbcreate_table :concert_details do |t| t.references :concert, foreign_key: true t.integer :grade t.integer :price t.integer :capacity t.timestamps end販売表(Sale)テーブル
席種:seat_grade、席数:seats_total、販売日:sale_date、販売額:sales_total、決済期限日:payment_deadline、使用ポイント:used_point
=> grade , number_of_seats , date , amount , payment_deadline , used_point
このテーブルは安易にリネームすると尚更分かりづらくなるので、注意した。
販売額amountとごっちゃにならず、席数に最適な短い訳が思いつかないので、一応英語に従った。、db/migrate/(timestanp)_create_sales.rbcreate_table :sales do |t| t.references :concert, foreign_key: true t.references :user, foreign_key: true t.string :grade t.integer :number_of_seats t.datetime :date t.integer :amount t.datetime :payment_deadline t.integer :used_point t.timestamps end決済表(Payment)テーブル
決済日:payment_date、決済額:payment_total、付与ポイント:added_point
=> date , amount , added_pointdb/migrate/(timestanp)_create_payments.rbcreate_table :payments do |t| t.references :sale, foreign_key: true t.datetime :date t.integer :amount t.integer :added_point t.timestamps endseeds.rbファイルもカラム名を使用しているので、一部変更
terminalrails db:migrate:reset rails db:migrate rails db:seedER図を修正
あとは、controllerとviewを弄っていくか。
- 投稿日:2019-04-11T17:05:26+09:00
Rubyのバージョン指定があるプロジェクトで良くあるエラーと対処法
rbenv global 2.3.0などで、プロジェクトに応じてバージョンを下げた際に起こるエラーに対しての対処法。
$ rails s rbenv: rails: command not found The `rails' command exists in these Ruby versions: 2.3.0 2.3.1 2.6.2こんなエラーが出てしまった・・・・・
対処法
gem i -v 5.1.3 railsこれでもだめ、、、、、、
Gemfile.lockにあるbundlerのバージョンに合わせて、インストール
$ gem install bundler -v 1.3.0これで行けた!!
ただ、bundle installする時に、エラー文に沿ってGemfileの修正が必要。
- 投稿日:2019-04-11T16:39:48+09:00
なぜあなたは初心者エンジニアから脱出できないのか
概要
タイトルの通り。それ以上でもそれ以下でもありません。
自分自身がRubyとRailsをゴリゴリやっていたのに初心者からいつまでも抜け出せないなぁというところから今に至ります。
とくに初心者から抜け出せない、だけど将来はエンジニアになりたい独学大学生に送りたい。なぜ初心者か
ずっとRubyとRailsを書き、それにこだわってきたときは気づけなかったんですが、答えは単純。RubyとRailsは知ってても他のことは知らなかったから。
要はコンピューター内で動くプログラムは少しかじれてたけど、動く機械のことを知らなさ過ぎたから。
要はコンピューターサイエンスについてだったりWebの知識がない。(Webアプリを作りながらこの状況だからそりゃ脱出はできない。)Railsにこだわりすぎた
Railsは一行でいろいろできすぎる。
すごくありがたいけど、そのせいで理解したフリで先へ先へとすすめてしまっている。(特にScaffoldはよくないと思ってる。)
知識があって省略するのと、知らないまま省略するのでは大きな差があるとめちゃめちゃに実感した。要はフレームワークはRailsに限らず便利でいいんだけど、ちゃんと同時に知識をつけないと無知のまま世界が広がることになる。
作ってたり勉強している分には別にどうってことないけれど、仕事にするぞ、ってなったときに、苦労が半端じゃない。言語の選び方が雑だった
正直最初は興味のある分野、言語をやっていいと思う。入りがつまらないとしんどいし、やめてしまうから。実際自分も最初はゲームを作りたくてUnityとC#を触ってキャッキャウフフしてた。
だけど、その後職業としてWEBエンジニアになりたいと勉強し始めた方法が失敗だった。RubyとRailsは学習コスト的に楽そうだと始めた。確かに楽だった。でも昔の人はいい事を言うもので、楽あれば苦あり。のちに苦が訪れた。
確かに手を動かして、ポートフォリオを作ってみたいなところは簡単に進む。だけれども小手先感が半端じゃない。それは当然で、あとから考えれば本当に必要な知識はついていなかったのだから。どうやったら脱出できるのか
正直なところ、今抜け出そうとしている最中だからわからない。ただ、WEBやコンピューターサイエンスの勉強をしていると、少しずつブラックボックスになっていたことはわかってきた。
こうして一個一個知らないことをつぶすほかないと思う。正直面倒だし、地味だけどすごい大切。
RubyやRailsも初心者がやっちゃダメというわけでなくて、ただちゃんと理解してますか?って考えながらやった方がいい。(あと個人的にはこれらはMVPがすぐほしいStart Upがやるといいのかなぁと思ったりもする。あとはちゃんと勉強できる人。)終わりに
職業でエンジニアになりたい、という人以外は別に初心者から抜け出さなくてもいいと思う。大変だし。
ただ、もしエンジニアに何が何でもなる、というなら、手を動かすだけなのもダメな気がする。ちゃんと勉強して、なぜ動くか、どう動くかきっちり確認する。
車を運転する人は中でどう動作するか知らなくてもいいけど、作ったりメンテナンスする人が適当な理解はまずいに決まっている。ちゃんと勉強していった方が、遠回りかもしれないけど、必要なことだと思う。
- 投稿日:2019-04-11T14:34:59+09:00
[学習用]Rails5にてCarrierWaveでサムネイル画像と最大画像と拡張子の制限をしたアプリを作る
スムーズにうまく行ったのでメモ。
Ralis5 Ubuntu16GemFileに追加する
gem 'carrierwave' gem 'mini_magick'コマンド入力
$ bundle $ rails g scaffold upload image:string content:text name:string $ rails g uploader images $ rails db:migrate必要事項の追記
Scaffoldで作ったuploadのmodelsに追記
app/models/upload.rbclass Upload < ApplicationRecord mount_uploader :image, ImagesUploader endCarrierWaveのファイルに追加
app/uploaders/images_uploader.rbclass ImagesUploader < CarrierWave::Uploader::Base # Include RMagick or MiniMagick support: # include CarrierWave::RMagick include CarrierWave::MiniMagick # Choose what kind of storage to use for this uploader: storage :file # storage :fog # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end # 許可する画像の拡張子 def extension_whitelist %w(jpg jpeg gif png) end # サムネイル画像 version :thumb do process resize_to_fill: [80, 80] end # Maxサイズ version :content do process resize_to_limit: [640, 640] end endViewsファイルを修正・追加
_horm.html.erb
app/views/uploads/_horm.html.erb<div class="field"> <%= form.label :image %> <%= form.file_field :image %> </div>show.html.erb
app/views/uploads/show.html.erb<%= image_tag @upload.image_url(:content) if @upload.image.present? %>index.html.erb
app/views/uploads/index.html.erb<table> <thead> <tr> <th>Image</th> <th>Content</th> <th>Name</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @uploads.each do |upload| %> <tr> <td> <%= image_tag upload.image_url(:thumb) if upload.image.present? %> </td> <td><%= upload.content %></td> <td><%= upload.name %></td> <td><%= link_to 'Show', upload %></td> <td><%= link_to 'Edit', edit_upload_path(upload) %></td> <td><%= link_to 'Destroy', upload, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table>これで画像のサムネイル投稿、最大サイズの制限、投稿拡張子の制限ができる。
サムネイルには
ImageMagick が必要なのでサーバーに入れてない場合は入れる。
画像にリンクをつける
app/views/uploads/index.html.erb<%= link_to (image_tag upload.image_url(:thumb) if upload.image.present?), upload %>または
app/views/uploads/index.html.erb<%= link_to upload do %> <%= image_tag upload.image_url(:thumb) if upload.image.present? %> <% end %>サムネイル画像
詳細ページの最大画像
- 投稿日:2019-04-11T12:29:20+09:00
Ruby on Rails で動画投稿機能を実装してみた
基本的には画像の投稿と同じ
1.carrierwaveの導入
2.カラムを追加
3.モデルにアップローダを追加
4.コントローラにパラメータ追加
5.フォームの作成
6.ビューに表示1.carrierwaveの導入
Gemfilegem 'carrierwave'Gemfileに追記↑
ターミナル$ bundle installrails s 再起動忘れないように...
ターミナル$ rails g uploader videocarrierwave generatorを使用しビデオをアップロードするためのアップローダを作成する。
app/uploaders/video_uploader.rb が生成されていることを確認。2.モデルでカラムを追加
ターミナル$ rails g migration add_video_to_post video:string # rails g migration add_カラム名_to_モデル名 カラム名:stringターミナル$ rake db:migrate3.モデルにアップローダを追加
tweet.rbclass Tweet < ApplicationRecord mount_uploader :video, VideoUploader # mount_uploader :カラム名, carrierwaveの設定ファイルのクラス名 end4.コントローラにパラメータ追加
tweets_controller.rbclass TweetsController < ApplicationController #(略) def new @tweet = Tweet.new end def create @tweet = Tweet.create(tweet_params) end private def tweet_params params.require(:tweet).permit(:video) #params.require(:モデル名).permit(:カラム名) end end5.フォームの作成
new.html.haml= form_for @tweet do |f| = f.file_field :video = f.submit "送信"6.ビューに表示
index.html.haml= video_tag tweet.video_url.to_s,loop: true, controls: true,; #loop: true loop処理
- 投稿日:2019-04-11T12:19:30+09:00
RailsアプリをHeroku上で、NginxとUnicornで動かす方法
unicornの導入
Gemfilegem 'unicorn'追加し、bundle install
Procfileも編集するが、後でnginxの設定をするために、ここではやらない。
※参考サイト
https://workabroad.jp/posts/1225nginxの導入
※参考サイト
https://github.com/heroku/heroku-buildpack-nginx
あとは、このサイトのSetupに沿って進めていく。herokuにデプロイできたら、下記コマンドで確認。
heroku logs -t約2日間、分からずに積んだため、このようにまとめました。
- 投稿日:2019-04-11T11:40:47+09:00
Oauth2.0 providerをrailsで作る
以下の記事を参考
https://qiita.com/kyonsuke19101/items/407f3cdfec38d1108e9dエラー回避
403error → admin_authenticatorのコメント欄をactivation
adminカラムをuserに追加
root to: 'home#show'をroutesに追加
- 投稿日:2019-04-11T10:58:40+09:00
ratyrateを使用したRailsの星型評価を実装する
Railsで星の評価機能を実装する方法です。
環境
Rails 5.2.3
mysql
gem ratyrate
gem deviseGoals
以下のように星の評価を実装したアプリの作成
GitHub:testGemRatyrate背景
Railsで星の評価機能を実装しようとした際、
jquery.ratyを使用する方法は参考記事が沢山あるのですが、jqueryの知識を要求されたり、画像をダウンロードしたりと手間がかかります。もっと手軽に実現できないか調べたところ、
ratyrateというgemがあることを知りました。
しかし、Rails5.2.3では公式の方法ではエラーで使用することができませんでした。そこで、Rails5.2.3で使用する方法をまとめました。
準備
ratyrateのインストール
ratyrateはjqueryを使用しているので、jquery-railsも一緒にインストールします。
また、deviseと連携させるのでdeviseも加えます。
Gemfileに以下をグローバルに記入します。gem 'devise' gem 'jquery-rails' gem 'ratyrate'インストールをします。
bundle install評価者の設定
devise:userとratyrateを作成します。
rails g devise:install rails g devise user # 以下を実行すると、星画像やmigrationファイル等が作成される rails g ratyrate userMigration
生成されるmirationファイルは、以下の4つになります。
-db/migrate/20140814135421_create_rating_caches.rb
-db/migrate/20140706144643_create_rates.rb
-db/migrate/20140814135422_create_average_caches.rb
-db/migrate/20140814135423_create_overall_averages.rbこの状態でmigrationを実行するとエラーになり、migrationに失敗してしまいます。
そこで、各ファイルを以下のように編集します。create_rating_caches.rb
class CreateRatingCaches < ActiveRecord::Migration[5.2] def self.up create_table :rating_caches do |t| t.belongs_to :cacheable, :polymorphic => true t.float :avg, :null => false t.integer :qty, :null => false t.string :dimension t.timestamps end end def self.down drop_table :rating_caches end endcreate_rates.rb
class CreateRates < ActiveRecord::Migration[5.2] def self.change create_table :rates do |t| t.belongs_to :rater t.belongs_to :rateable, :polymorphic => true t.float :stars, :null => false t.string :dimension t.timestamps end end def self.down drop_table :rates end endcreate_average_caches.rb
class CreateAverageCaches < ActiveRecord::Migration[5.2] def self.up create_table :average_caches do |t| t.belongs_to :rater t.belongs_to :rateable, :polymorphic => true t.float :avg, :null => false t.timestamps end end def self.down drop_table :average_caches end endcreate_overall_averages.rb
class CreateOverallAverages < ActiveRecord::Migration[5.2] def self.up create_table :overall_averages do |t| t.belongs_to :rateable, :polymorphic => true t.float :overall_avg, :null => false t.timestamps end end def self.down drop_table :overall_averages end end編集したらmigrationを実施します。
rails db:migratejavascriptの読み込み
app/assets/javascripts/application.jsに以下を追記します。
この時、//= require rails-ujsより上に記述します。//= require jquery //= require jquery.raty //= require ratyrate以上で、ratyrateを使用する準備が整いました。
アプリ作成
実際にratyrateを実装したアプリを作成します。
作成するアプリは車のスピードを評価するものです。準備
scaffoldを使用してモデルを作成
rails g scaffold car name:stringmigrationを実施します。
rails db:migrateコードの編集
メインとなる箇所を抜粋します。
Model
car.rb
class Car < ApplicationRecord ratyrate_rateable "speed" # 追加 end補足:
ratyrate_rateableで評価対象となる項目を指定します。
複数ある場合は、カンマ区切りになります。例:
ratyrate_rateable "speed", "engine", "price"user.rb
class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable ratyrate_rater # 追加 endView
app/views/cars/show.html.erb
星を表示したい場所へ以下を記述します。
<p>Speed : <%= rating_for @car, 'speed' %></p>以上で完成です。
その他オプション
再評価
デフォルトの設定では、一旦評価すると変更できません。
そこで以下のオプションを付けることで、評価を変更できるようになります。<%= rating_for @car, 'speed', disable_after_rate: false %>星の数の変更
<%= rating_for @car, 'speed', star: 10 %>星半分
<%= rating_for @car, 'speed', disable_after_rate: false, enable_half: true %>平均値の表示
<%= rating_for car, 'speed', disable_after_rate: true, imdb_avg: true %>その他にもオプションが用意されているので、wazery/ratyrateやRatyrate: Add Rating to Your Rails Appで確認してください。
最後に
ratyrateを使用することで、評価用のテーブルは不要になり、実装もシンプルでスマートになりました。
参考
- 投稿日:2019-04-11T10:47:04+09:00
ポートが既に使われているエラーの場合は、不要なポート番号を削除する。
Address already in use... のエラー
Railsにて
$rails sを実行時、下記のようなERRORが発生した。$ rails s . . . /Users/kikkutonton/.rbenv/gems/2.6.0/gems/puma-3.12.1/lib/puma/binder.rb:273:in `initialize': Address already in use - bind(2) for "::1" po rt 3000 (Errno::EADDRINUSE)エラー原因
エラー文通り、
localhost:3000のポートが既に他のポートに使われていることが原因のエラー。対処法
不要なポートを削除する。
使われているポート番号を確認
$sudo lsof -i:3000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME com.docke 17067 kikkutonton 22u IPv4 0xeexxxxxxxxxxxxxx 0t0 TCP *:hbci (LISTEN) com.docke 17067 kikkutonton 23u IPv6 0xeeyyyyyyyyyyyyyy 0t0 TCP localhost:hbci (LISTEN)使用ポートを削除
//PID番号 $sudo kill xxxx
- 投稿日:2019-04-11T04:07:25+09:00
気持ちいいRuby/Ruby on Rails開発環境を作ったので解説(Mac/Win両対応)
hayakasa/docker-vagrant-template-rails
以下の要件を満たすRuby/Ruby on Railsの開発・実行環境を環境を作成しました。
- ホストOSの環境を極力汚さないこと
- 必要最低限の手順で環境構築できること
- 実行環境のバージョンを管理する手間を極力省くこと
- ソースコードを共有ディレクトリでマウントし、編集後に即時反映されること
- Dockerコンテナ側からファイル操作が可能なこと(bundle install、tmp内のファイル作成など)
- Mac・Windowsどちらでも可能な限り同じ手順で構築し動作すること
rvm、rbenvなどで実行環境のバージョン管理をすることが手間に感じていたのでDockerを採用することを決めたのですが、公式で配布されているDocker Desktop for Mac/Windowsにはソースコードを即時反映できるようにマウントした場合に実行速度が遅くなるなどの問題があります。
この問題を解決するため、ホストOSとDockerコンテナの間にVagrantで管理するVMを挟み、共有ディレクトリをNFSでマウントすることによって実行速度を犠牲にせずにアプリ開発ができる環境を作りました。前提アプリケーションのインストールや使い方は下記GitHubリポジトリのREADMEを参照ください。
hayakasa/docker-vagrant-template-railsこちらでは、少し突っ込んだ解説を行います。
NFSについて
Vagrantfileの以下の設定で共有ディレクトリをNFSマウントしています。
Vagrantfileconfig.vm.synced_folder ".", "/vagrant-nfs",type:"nfs" #DocRootをvagrant-nfsという名前でNFSマウントMacの場合
Macでは標準でNFSサーバーが準備されているので以下のコマンドで有効化します。
YourPC$ sudo touch /etc/exports #nfsd設定を保存するファイルを作成 YourPC$ sudo nfsd enable #nfsdの有効化Windowsの場合
WindowsではVagrantのプラグインを使うことによってNFSサーバーを立てずにNFSでマウントができるためそちらを使用します。
YourPC$ vagrant plugin install vagrant-winnfsdvagrant-bindfsプラグインについて
NFSでマウントした共有ディレクトリはホストOSのユーザーがownerになっているので、bindfsでvagrantユーザーがownerになるようにマウントし直します。
Vagrantfileconfig.bindfs.bind_folder "/vagrant-nfs", "/vagrant" #vagrant-nfsをvagrantという名前でbindfsマウントvagrant-hostsupdaterプラグインについて
vagrant upでVMを起動するときにhostsファイルにホスト名の登録を行います。これによってホスト名でアプリケーションにアクセスすることができるようになります。
(hostsを操作するためWindowsではコマンドプロンプト・PowerShellを管理者権限で実行する必要があります)Vagrantfileconfig.vm.hostname = "myapp.localhost"ポートフォワーディングについて
以下の設定によって一般的に使用されるポートでホストOSからアクセスができるようにしています。
docker-compose.ymlservices: db: ports: - "5432:5432" #例:PostgreSQLの場合。Dockerコンテナの5432番をVMの5432番にポートフォワーディング app: command: bundle exec rails s -p 3000 -b '0.0.0.0' --no-dev-caching #rails s を3000番ポートで実行 ports: - "80:3000" #Dockerコンテナの3000番ポートをVMの80番にポートフォワーディングVagrantfileconfig.vm.network "forwarded_port", guest: 80, host: 80 #VMの80番をホストOSの80番にポートフォワーディング config.vm.network "forwarded_port", guest: 5432, host: 5432 #VMの5432番をホストOSの5432番にポートフォワーディングデータベースのvolumeについて
以下の設定によってデータベースの内容はVM内で永続化しています。したがってVMのイメージ自体を削除しない限り、Dockerコンテナを破棄してもデータベースの中身は保持されます。
docker-compose.ymlservices: db: volumes: - /data/db:/var/lib/postgresql/data #例:PostgreSQLの場合 Dockerコンテナの/var/lib/postgresql/dataをVMの/data/dbに保存します
- 投稿日:2019-04-11T02:14:10+09:00
Ruby on Railsで下書き機能を実装するために場合分けしてみた
はじめまして。
Ruby on Rails勉強中のfkdollyと申します。
現在のところ独学での勉強につき、間違っている箇所があればご指摘いただければ幸いです。現在Railsでアプリを開発中でして、その中で投稿に下書き機能をつけたいと思い、下記の記事を始めとして色々調べてみました。
Railsで下書き機能を独自に実装した時の過程をまとめてみたですが、モデルをもう一つ作るとより頭がこんがらがりそうだったので(笑)、Postモデルの中で何とかする方法を考えました。
まず、搭載する下書き機能について以下のようなものを考えました。
- 投稿一覧画面では投稿した本人がログインしている時のみ下書き一覧を表示する。他のユーザーまたは未ログインユーザーがアクセスしても公開済みの投稿のみ表示。
- 投稿詳細画面も同様に下書きを投稿した本人がログインしている時のみアクセス可能。その他のユーザーはアクセス不可。公開済み記事には全ユーザーがアクセス可能。
そこでPostテーブルにStatusカラムを追加し、Draft/Publishのどちらかによって下書き/公開済みを切り替えることとしました。
また、アクセスしたユーザーが本人かどうかについてはセッションで判断することとしました。users_controller.rbdef login @user = User.find_by!(name: params[:name], password: params[:password]) if @user session[:user_id] = @user.id flash[:notice] = "ログインしました" redirect_to("/#{@user.id}") else redirect_to("/login") end endユーザー本人か否か/Draft記事があるか否か/Publish記事があるか否かの2×2×2=8通りなので条件分岐していきます。Userモデルのshowアクションでそのユーザーの投稿一覧を表示しており、下記のように書きました。
show.html.erb<% posts_draft = Post.where(user_id: @user.id, status: "draft") %> <% posts_publish = Post.where(user_id: @user.id, status: "publish") %> # ユーザー本人かつ下書きも公開済み記事もある場合 <% if session[:user_id] == @user.id && posts_draft.present? && posts_publish.present? %> <div class="post_status">下書きが残っています。投稿を公開しよう!</div> <% posts_draft.each do |post| %> # Draft一覧 <% end %> <div class="post_status">公開済み</div> <% posts_publish.each do |post| %> # Publish一覧 <% end %> # ユーザー本人かつ下書きのみある場合 <% elsif session[:user_id] == @user.id && posts_draft.present? && posts_publish.empty? %> <div class="post_status">下書きが残っています。投稿を公開しよう!</div> <% posts_draft.each do |post| %> # Draft一覧 <% end %> # ユーザー本人かつ公開済み記事のみある場合 <% elsif session[:user_id] == @user.id && posts_draft.empty? && posts_publish.present? %> <div class="post_status">公開済み</div> <% posts_publish.each do |post| %> # Publish一覧 <% end %> # ユーザー本人かつ下書きも公開済み記事も無い場合 <% elsif session[:user_id] == @user.id && posts_draft.empty? && posts_publish.empty? %> <div class="post_not_yet">投稿はありません。投稿しよう!</div> <% end %> # その他のユーザーかつ下書きも公開済み記事もある場合、または公開済み記事のみある場合 <% elsif (session[:user_id] != @user.id && posts_draft.present? && posts_publish.present?) || (session[:user_id] != @user.id && posts_draft.empty? && posts_publish.present?) %> <% posts_publish.each do |post| %> # Publish一覧 <% end %> # その他のユーザーかつ下書きのみある場合、または下書きも公開済み記事も無い場合 <% else %> <div class="post_not_yet">投稿はありません。</div> <% end %> <% end %>下2つは表示する内容が同じなのでまとめた結果6通りの場合分けになりました。
実際のコードではユーザー本人によるアクセスの場合は編集ボタンと削除ボタンも表示しています。また、投稿詳細画面はPostモデルのshowアクションで表示しています。上記のコードで画面上は表示されませんが、URLを直接入力するとアクセスできてしまうので、コントローラで下記のようにしました。
post_controller.rbdef show @post = Post.find_by(id: params[:id]) @user = User.find_by(id: @post.user_id) if session[:user_id] == nil && @post.status == "draft" redirect_to("/login") elsif session[:user_id] != @user.id && @post.status == "draft" redirect_to("/#{@current_user.id}") end end以上のような形で実装してみました。今のところは問題ないハズです。
が、要素がこれ以上増えるとこうした場合分けを使うのは現実的では無いと思うので別の方法も勉強してみたいと思います。やっぱりもっとシンプルにできる気がする...
こういう方法もあるよ!というのがあればぜひ教えてください!
- 投稿日:2019-04-11T01:05:11+09:00
LINEBOT + RailsでWikipediabotを作ってみました。
はじめに
Railsの勉強のためにLINEBOTを作ってみました。
内容はLineメッセージに調べたい単語を送信すれば、Wikipediaの概要とurlを返すものです。LineBotの設定
下記のリンクを参考に設定しました。ありがとうございます。
今更ながらRails5+line-bot-sdk-ruby+HerokuでLineBot作成してみたら、色々詰まったのでまとめました。
Wikipediaの情報取得
Wikipediaの情報を取得するためにAPiがあったので、そちらを利用しました。
wikipedia-clientGemgilegem 'wikipedia-client'$ bundle installControllerを編集
linebot_controller.rbclass LinebotController < ApplicationController require 'line/bot' require 'wikipedia' # callbackアクションのCSRFトークン認証を無効 protect_from_forgery :except => [:callback] def client @client ||= Line::Bot::Client.new { |config| config.channel_secret = ENV["LINE_CHANNEL_SECRET"] config.channel_token = ENV["LINE_CHANNEL_TOKEN"] } end def callback body = request.body.read signature = request.env['HTTP_X_LINE_SIGNATURE'] unless client.validate_signature(body, signature) head :bad_request end events = client.parse_events_from(body) events.each { |event| if event.message['text'] != nil # LINEで送られてきた文書を取得 word = event.message['text'] # 日本語版Wikipediaを設定 Wikipedia.Configure { domain 'ja.wikipedia.org' path 'w/api.php' } end # wikipediaから情報取得 page = Wikipedia.find(word) # 概要とURLを返す response = page.summary + "\n" + page.fullurl case event # メッセージが送信された場合 when Line::Bot::Event::Message case event.type # メッセージが送られて来た場合 when Line::Bot::Event::MessageType::Text message = { type: 'text', text: response } client.reply_message(event['replyToken'], message) end end } head :ok end endあとはherokuにデブロイして、動作確認すれば完成です。
動作イメージ
まとめ
簡単なまとめになりましたが以上になります。
結構簡単に実装できました。APIと組み合わせれば色々使えるんじゃないかなと思いました。
何かご指摘等がございましたらコメントよろしくお願いします。参考サイト
今更ながらRails5+line-bot-sdk-ruby+HerokuでLineBot作成してみたら、色々詰まったのでまとめました。










