20211007のRubyに関する記事は11件です。

バリデーションとは!

①結論! バリデーションとは、データの入力に制約をかけるという事です! データを登録する際に、一定の制約をかけることを言います! 例えば、以下のようなものがあります! ・空のデータが登録できないようにする!(ブログ記事など) ・既に登録されている文字列を登録できないようにする!(メールアドレスの登録など) ・文字数制限をかける!(パスワードなど) バリデーションを設ける際は、モデルにvalidatesメソッドを記述します! ②.validatesメソッド validatesとは、バリデーションを設定する時に使用するメソッドです! 以下が記述方法になります! モデルファイルへ記述 validates :カラム名, バリデーションの種類 これが書き方です! 続いて下記の例は、presence: trueと記述することで、nameカラムが「空ではないか」というバリデーションを設けています! モデルファイルへ記述 validates :name, presence: true これで完成です! このバリデーションを設けることで、名前が空欄の時データベースに保存できなくなります! つまり、値を必ず入れなければいけません! もし、空欄で登録しようとすると、エラーが発生します! 他にも種類がたくさんあるので、徐々にアウトプットして行こうと思います! ③.まとめ よく使用するので、覚えておくべきですね! バリデーションだけでも、かなりの種類があるみたいですね汗 確実に理解していかないとです! 何か説明で間違っていたらご指導お願い致します(_ _)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めてのオリジナルアプリ公開までの道のり

公開までの道のり 月 やってたこと 5月 tech camp(教養コース入学) 7月 tech camp(転職コース入学、夜間休日タイプ) 8月 カリキュラム終了 9月 オリアプ作成開始 10月 オリアプ完成 卒業予定は1月、笑 公開したアプリの概 アプリ名 FX-Traders https://fxtraders.jp どんなアプリ? fx取引の記録を公開できるアプリになります。そしてその記録をもとにグラフを作り結果を解析できるアプリです。 それを公開することで 自身が決めた取引ルールの厳守 取引ルールのブラッシュアップ 第三者からのフィードバック 他者取引への理解 などを狙っています。 なんで作ったの? まずは自分で欲しかったから。一番大きな理由でもありますね。学生の頃にfxの記録を紙のノートに書いていて、画像を残せないのが残念で書くだけで満足していて、笑笑 こんなことを思っている人がたくさんいるんじゃないか?って思ったのも作った理由のひとつです。 あとはコロナ禍で投資を始める人も増えていることが想定されますから需要もあるかと思ってもいます。 なので、 自分が使いたい あるといいなと思っている人もいるのでは? コロナ禍で投資人口も増えているのでは? と言うところでこのアプリを作りました! アプリ実装項目 取引記録 投稿 編集 削除 検索(gem, ransack) 画像投稿(gem, active storage) いいね機能(ajax, font awesome) 取引手法 投稿 編集 削除 検索(rgem, ansack) 画像投稿(gem, active storage) いいね機能(ajax, font awesome) コメント 投稿(ajax) 削除(ajax) ユーザー関連 フォロー機能 グラフ表示(gem, chartkick) メール認証機能 管理者機能 seo対策 メタtag(gem, meta_tags) ぱんクズリスト(gem, gretel) サイトマップ(gem, sitemap_generator) サイトマップの自動更新(gem, whenever) デプロイ aws(ec2, s3, route53) mysql(maria DB) Unicorn Nginx 自動デプロイ(gem, Capistrano) ssl証明(AWS, ACM) その他 ページネーション 日本語対応(gem, rails-i18n) 広告のランダム表示 問い合わせ(ライン公式, font awesome) ハンバーガーメニュー PV数(閲覧数)取得(gem, impressionist) OGPの設定(gem, meta-tags) アプリを作った感想 勉強期間は約3ヶ月ですが自分的には満足できるものができました。が、まだ実装したいことがたくさんあるので追加実装を続けていく予定です。 さらにreact, react nativeを勉強していきたいなと思っています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

`rails s` 実行時にRubyGemsのエラーが発生する

環境情報 macOS Big Sur 11.6 Ruby 2.6.1 Rails 5.2.6 起きたこと OSのアップデートやrbenvの再インストールを行った後、 rails s や rails c を実行した時に下記エラーが発生するようになってしまった   (起きていた現象として、エラーが発生するだけで起動は行われる) /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/rubygems_integration.rb:12: warning: already initialized constant Bundler::RubygemsIntegration::EXT_LOCK /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/rubygems_integration.rb:12: warning: previous definition of EXT_LOCK was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/version.rb:4: warning: already initialized constant Bundler::VERSION /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/version.rb:10: warning: previous definition of VERSION was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/constants.rb:4: warning: already initialized constant Bundler::WINDOWS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/constants.rb:4: warning: previous definition of WINDOWS was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/constants.rb:5: warning: already initialized constant Bundler::FREEBSD /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/constants.rb:5: warning: previous definition of FREEBSD was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/constants.rb:6: warning: already initialized constant Bundler::NULL /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/constants.rb:6: warning: previous definition of NULL was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/current_ruby.rb:12: warning: already initialized constant Bundler::CurrentRuby::KNOWN_MINOR_VERSIONS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/current_ruby.rb:12: warning: previous definition of KNOWN_MINOR_VERSIONS was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/current_ruby.rb:26: warning: already initialized constant Bundler::CurrentRuby::KNOWN_MAJOR_VERSIONS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/current_ruby.rb:24: warning: previous definition of KNOWN_MAJOR_VERSIONS was here /path/to/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/bundler-2.2.28/lib/bundler/current_ruby.rb:28: warning: already initialized constant Bundler::CurrentRuby::KNOWN_PLATFORMS /path/to/.rbenv/versions/2.6.1/lib/ruby/2.6.0/bundler/current_ruby.rb:26: warning: previous definition of KNOWN_PLATFORMS was here 解決方法 gem update --system を実行する(gemコマンドをアップデートする) 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby 正規表現を使用して文字列からほしい文字を取得する!! 【gsubメソッド】【sliceメソッド】【scanメソッド】【最短マッチ】

前回の記事で取得したツイートから必要な内容を取得したい!!!と思い正規表現についてググったものをまとめていきます:) 正規表現 正規表現(regular expression)は文字列のパターンを記述するための言語です。また、この言語で記述されたパターンも正規表現と呼びます。 正規表現を用いると、文字列が指定したパターンを含んでいるかどうかを判定し、また含んでいるならばそれが文字列中のどの場所であるかを知ることができます。 Ruby 3.0.0 リファレンスマニュアル > 正規表現 今回取得したツイート このツイートから値段 ブランド アイテム名 を取得したい! 【GUCCI】 インターロッキングGシルバー ¥40,700- tax in 【Lansing store】 アロマキャンドル(4個) ¥3,000-前後 参考価格 ★フレンチバニラ ★ガーデニア 【JBL】 Pulse 4 ¥21,780- tax in gsubメソッド 文字列中で pattern にマッチする部分全てを文字列 replace で置き換えた文字列を生成して返します。 Ruby 3.0.0 リファレンスマニュアル > gsub このメソッドを使用して、ツイートの段落部分を無くす。 # textにツイート内容を代入する text = "【GUCCI】 インターロッキングGシルバー ¥40,700- tax in 【Lansing store】 アロマキャンドル(4個) ¥3,000-前後 参考価格 ★フレンチバニラ ★ガーデニア 【JBL】 Pulse 4 ¥21,780- tax in" => "【GUCCI】\nインターロッキングGシルバー\n¥40,700- tax in\n\n【Lansing store】\nアロマキャンドル(4個)\n¥3,000-前後 参考価格\n★フレンチバニラ\n★ガーデニア\n\n【JBL】\nPulse 4\n¥21,780- tax in" # gsubメソッドを使用して段落をなくす irb(main):014:0> text_content = text.gsub(/[\r\n]/,"") => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" sliceメソッド 指定された自身の要素を返します。Array#[] と同じです。 Ruby 3.0.0 リファレンスマニュアル > slice irb(main):001:0> a = "(111)と【222】" => "(111)と【222】" irb(main):002:0> a.slice(/(?<=\().*?(?=\))/) => "111" irb(main):003:0> a.slice(/(?<=\【).*?(?=\】)/) => "222" このような形で取得することができる。 aにはこのように文字列が代入されている。 a = "(111)と【222】" slice.(/(?<=\().*?(?=\))/)で()内の文字を取得している slice.(/(?<=\【).*?(?=\】)/)で【】内の文字を取得している これでいける!!と思ったが複数該当するものがあるとうまくいかないことに気づいた... 前提としてtweet_contentまで代入しておく # textにツイート内容を代入する irb(main):001:0> text = "【GUCCI】 インターロッキングGシルバー ¥40,700- tax in 【Lansing store】 アロマキャンドル(4個) ¥3,000-前後 参考価格 ★フレンチバニラ ★ガーデニア 【JBL】 Pulse 4 ¥21,780- tax in" => "【GUCCI】\nインターロッキングGシルバー\n¥40,700- tax in\n\n【Lansing store】\nアロマキャンドル(4個)\n¥3,000-前後 参考価格\n★フレンチバニラ\n★ガーデニア\n\n【JBL】\nPulse 4\n¥21,780- tax in" # gsubメソッドを使用して段落をなくす irb(main):014:0> text_content = text.gsub(/[\r\n]/,"") => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" slice(/¥.*-/)を使用して¥と-の間の文字を取得する irb(main):015:0> price = text_content.slice(/¥.*-/) => "¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-" slice(/(?<=\【).*?(?=\】)/)を使用して【と】の間の文字を取得する irb(main):016:0> brand = text_content.slice(/(?<=\【).*?(?=\】)/) => "GUCCI" slice(/(?<=\】).*?(?=\¥)/)を使用して】と¥の間の文字を取得する irb(main):017:0> item = text_content.slice(/(?<=\】).*?(?=\¥)/) => "インターロッキングGシルバー" 結果 ・複数当てはまってしまう部分があり、うまくいかない箇所がある ・値段がうまく取得できていない scanメソッド self に対して pattern を繰り返しマッチし、マッチした部分文字列の配列を返します。 pattern が正規表現で括弧を含む場合は、括弧で括られたパターンにマッチした部分文字列の配列の配列を返します。 Ruby 3.0.0 リファレンスマニュアル > scan 該当している文字を複数個取得したいのでscanメソッド使用してみる # 前提としてtext_contentに代入してあるものとする irb(main):044:0> text_content => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" scan(/¥.*-/)を使用して¥と-の間の文字を取得する irb(main):045:0> price = text_content.scan(/¥.*-/) => ["¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-"] scan(/(?<=\【).*?(?=\】)/)を使用して【と】の間の文字を取得する irb(main):046:0> brand = text_content.scan(/(?<=\【).*?(?=\】)/) => ["GUCCI", "Lansing store", "JBL"] scan(/(?<=\】).*?(?=\¥)/)を使用して】と¥の間の文字を取得する irb(main):047:0> item = text_content.scan(/(?<=\】).*?(?=\¥)/) => ["インターロッキングGシルバー", "アロマキャンドル(4個)", "Pulse 4"] 結果 price (値段)だけうまく取得できない 正規表現の最短マッチを使用する 最短マッチについてはこちらを参考にさせていただきました! これで分かった!最短マッチ - Qiita 問題のある部分 scan(/¥.*-/)を使用して¥と-の間の文字を取得する irb(main):045:0> price = text_content.scan(/¥.*-/) => ["¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-"] 1.「+」と「*」の違いについて *から+に変更する *は0文字以上でマッチするのでこの形でもマッチしてしまう。 値段がない時は取得したくない。 irb(main):064:0> text = "インターロッキングGシルバー¥- tax in" => "インターロッキングGシルバー¥- tax in" irb(main):065:0> price = text.scan(/¥.*-/) => ["¥-"] +は1文字以上でマッチするのでこの形でこのようになる。 今回はこっちを採用する! irb(main):067:0> text = "インターロッキングGシルバー¥- tax in" => "インターロッキングGシルバー¥- tax in" irb(main):069:0> price = text.scan(/¥.+-/) => [] 2.「?」を使用する ?を使用することで最短マッチを使用することができる 以下のようにprice = text_content.scan(/¥.+-/)に変更しただけでは根本的な解決にはつながっていない。 irb(main):075:0> text_content => "【GUCCI】インターロッキングGシルバー¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780- tax in" irb(main):076:0> price = text_content.scan(/¥.+-/) => ["¥40,700- tax in【Lansing store】アロマキャンドル(4個)¥3,000-前後 参考価格★フレンチバニラ★ガーデニア【JBL】Pulse 4¥21,780-"] price = text_content.scan(/¥.+?-/)に変更することでこのように取得することができる:) irb(main):077:0> price = text_content.scan(/¥.+?-/) => ["¥40,700-", "¥3,000-", "¥21,780-"] 結論 +によって 1文字以上を含んでる時にのみ文字を取得し、 ?によって 最短マッチを使用するため¥と-が最短で挟んでいる部分の文字を取得し、 scanメソッドを使用したことにより 複数ある場合は複数取得可能
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】便利な正規表現まとめ

オリジナルアプリ作成にあたり使用した正規表現を、備忘録としてアウトプットします。 英数字混合 ※大文字・小文字の区別なし /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i 半角数字のみ /\A[0-9]+\z/ 全角(漢字・ひらがな・カタカナ) /\A[ぁ-んァ-ヶ一-龥々ー]+\z/ ・ァ-ンではなくァ-ヶとしているのはヴ、ヵ、ヶを含めるため。 ・一-龥ではなく一-龥々としているのは々を含めるため。 ・末尾にーがあるのは「ジュリー」「メアリー」などのハイフンを含めるため。 全角(カタカナのみ) /\A[ァ-ヶー]+\z/ 電話番号10桁以上11桁以下(ハイフンなし) /\A[0-9]{10,11}+\z/ 郵便番号(ハイフンあり) /\A\d{3}[-]\d{4}\z/ 今回登場した正規表現のパターン表記一覧 [a-z]: 角括弧で囲まれた文字のいずれか 1個にマッチ \d:数字にマッチ {n, m}: 直前の文字が少なくともn回、多くてもm回出現するものにマッチ . :改行以外のどの1文字にもマッチ + :直前の文字の1回以上の繰り返しにマッチ \A :直後の文字が先頭にある文字列にマッチ \z :直前の文字が末尾にある文字列にマッチ [ぁ-んァ-ヶ一-龥々]: 角括弧に囲まれたかな、カナ、漢字のいずれかにマッチ(ヴ、ヵ、ヶ、々を含む) ?= :直後に設定した文字が続く文字列にマッチ *? :直前に設定した文字が0回以上続く文字列をチェックし、?の直後の文字が出た段階でその1文字を返す ご指摘などあれば、ご教授いただけると幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]非同期(Ajax)でのコメント機能実装

この記事の目的 非同期処理(ajax)でのコメント投稿機能を学んだのでアウトプットします 目標 要件 コメント投稿は非同期で行う 環境 ・Ruby 2.7.1 ・Rails 5.2.6 前提 ・UserとPostは作成済み ・bootstrapとjquery-railsが入っている 設計 ER図 ルーティング POST /posts/:post_id/comments comments#create GET /comments/:id/edit comments#edit PATCH /comments/:id comments#update DELETE /comments/:id comments#destroy ※ post_idが必要なのはコメントがcreateされる場合だけであり、一度コメントが作成されればそれらコメントは一意のidを持つので、edit,update,destroyの場合はコメントの自身のidのみで特定可能である。 よって、このようなルーティングにする。(shallow: trueで実現可能) このようなshallowルーティングのメリットは、shallowを使わない場合と比較してルーティングがスッキリするという点である。 実装 データベース $ rails g model Comment body:text user:references post:references実行 マイグレーションファイル編集(任意) $ rails db:migrate実行 モデル models/comment.rb class Comment < ApplicationRecord belongs_to :user belongs_to :post validates :body, presence: true, length: { maximum: 1000 } end models/user.rb has_many :comments, dependent: :destroy models/post.rb has_many :comments, dependent: :destroy ※ has_many,belongs_toはメソッドを作るためのメソッド。 ※ Userモデルにhas_many :commentsを記述することで、Userモデルのインスタンスは.commentsメソッドを使い、自身のidに対応するCommentモデルのuser_idを通じて、コメント情報にアクセスできるようになる。Postも同様。 ※ 逆に、Commentモデルにbelongs_to :userを記述することで、Commentモデルのインスタンスは.userメソッドを使い、自身のuser_idに対応するUserモデルのidを通じて、ユーザー情報にアクセスできるようになる。belongs_to :postでも同様。 ルーティング routes.rb resources :posts, shallow: true do resources :comments end ※ 上述したルーティング設計に合わせるため、shallowルーティングを使用している (参考:Railsの”shallow(浅い)”ルーティングを理解する) コントローラー comments_controller.rb class CommentsController < ApplicationController def create @comment = current_user.comments.build(comment_params) @comment.save end def edit @comment = current_user.comments.find(params[:id]) end def update @comment = current_user.comments.find(params[:id]) @comment.update(comment_update_params) end def destroy @comment = current_user.comments.find(params[:id]) @comment.destroy! end private def comment_params params.require(:comment).permit(:body).merge(post_id: params[:post_id]) end def comment_update_params params.require(:comment).permit(:body) end end ※ current_user.comments.findをComment.findにしてしまうと、コメントしたユーザー以外のユーザーがURL直打ちなどによって他人のコメントを編集できてしまうようになるので注意。 ※ ユーザから受け取った情報としてparamsにはないけれども、レコード作成時に追加したい値がある場合はmergeメソッドで含めることができる(今回のpost_id)。 mergeメソッドは、ハッシュ同士を統合できるメソッド。 例 x = {age: "25", email: "tarou@example.com"} {name: "太郎"}.merge(x) #=> {name: "太郎", age: "25", email: "tarou@example.com"} (参考) 【初学者向け】Rails mergeメソッド mergeメソッドについて改めて理解を深めた ※ buildメソッドはnewメソッドと同じ。慣習的に、関連するモデルを生成するときはbuildを使う(参考: railsのnewとbuildの違い) ※ createアクションの処理が終わると、views/comments/ディレクトリ配下にcreate.html.erbまたはcreate.js.erbを探しに行く。edit,update,destroyも同様。 view jsの記述 views/comments/create.js.erb <% if @comment.errors.present? %> alert("<%= @comment.errors.full_messages.join('\n') %>"); <% else %> $('.comments-box').prepend("<%= escape_javascript(render('comments/comment', comment: @comment) ) %>"); $('.input-comment-body').val(''); <% end %> ※ slimならRubyのコードを囲む<%=...%>は#{...}となる ※ escape_javascriptはjと省略して書くこともできる ※ 最初の<% if @comment.errors.present? %>の部分は、ユーザーのコメントがバリデーションに引っかかった場合にエラー文を表示する処理。 ・<% else %>の1行目の部分は、htmlのcomments-boxクラスで囲まれた部分にrender('comments/comment', comment: @comment) をぶちこんでいる。 イメージ <div class="comments-box"> <li>コメント1</li> <li>コメント2</li> <li>コメント3</li> <li>新規コメント</li> ⇦ こいつがjsで追加されるイメージ </div> 検証ツールで実際の挙動を確認 ※ コメントを投稿したとき、画面遷移はせずに<div id="comment-29">...</div>だけが追加されていることがわかる htmlの記述(投稿されたコメントの表示画面) views/posts/show.html.erb(postの詳細画面) ・ ・ ・ <hr> / コメント一覧 <%= render 'comments/comments', comments: @comments %> <hr class="m-0"> <div class="post-comment p-3"> <%= render 'comments/form', post: @post, comment: @comment %> </div> </hr> </hr> views/comments/_comments.html.erb <div class="comments-box"> <%= render comments %> </div> ※ commentsは@comments。つまりrender @commentsで_comment.html.erbに飛ばしているのと同じ(each文省略するやつ) views/comments/_comment.html.erb ( @comments.each do |comment| が省略されている ) (<div class="comments-box">) ・ ・ ・ / コメント一覧のうちのコメントひとつひとつ(|comment|) <div class="col-9"> <span class="font-weight-bold.pr-1"> <%= comment.user.username %> </span> <%= comment.body %> </div> (</div>) htmlの記述(コメントの入力フォーム) views/comments/_form.html.erb <%= form_with model: [post, comment], class: 'd-flex mb-0 flex-nowrap justify-content-between', remote: true do |f| %> <%= f.text_field :body, class: 'form-control input-comment-body', placeholder: 'コメント' %> <%= f.submit '投稿', class: 'btn btn-primary btn-raised' %> <% end %> ※ form_withはデフォルトでremote: trueなので書く必要はないが、local: trueではないことを強調するためにremote: trueを明示。 ちなみにlink_toの場合はremote: trueを必ず書かなければいけない。 ※ ルーティングをネストさせているのでmodel: [post, comment]と2つ書かなければいけない ※ もしform_with model: commentにしたら、/commentsにPOSTリクエストが送られるが、ルーティングのPOST /posts/:post_id/comments comments#createにマッチしないため、post_idが不存在ということでエラーが起きる。 ※ edit, update, destroyについてもcreate同様にviewを作っていく ちなみに、検証ツールを見ればTypeがxhrになっており、form_withのremote: trueが非同期処理をしていることがわかる。 XHR(XMLHttpRequest)とは、JavaScriptなどのウェブブラウザ搭載のスクリプト言語でサーバとのHTTP通信を行うための、組み込みオブジェクト(API)である。 すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。(Wikipedia引用)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gzip圧縮したデータを連結したデータはRubyのZlib::GzipReaderでは読めない

複数のGzipデータを連結した1つのデータ gzipコマンドは複数のgzip圧縮されたファイルをcatで結合したものでも展開することができます。簡単な例をbashで見てみましょう date --iso-8601=ns | gzip > a.gz date --iso-8601=ns | gzip > b.gz cat a.gz b.gz > all.gz gzip -dc all.gz # 2行出てくる RFC1952でファイルフォーマットについて説明があります。 Gzipファイルフォーマットは先頭10byteは必ずメンバ情報になっており、あとはメンバ情報のFLGによって可変長データが続くような形になっています。 この繰り返しなので、複数の圧縮されたデータがあっても、ひたすら展開して連結することで1つのデータが得られる仕組みになっているようです。上記の通り、gzipコマンドやzcatコマンドや著名なアーカイバ(7-zipとか)はサポートしています。 RubyのZlib::GzipReaderはサポートしているか? 2021/10/05時点の実装ではZlib::GzipReader.zcatでサポートしているようですが、RubyGemsで公開されているバージョン(1.1.0)ではまだ入っていないようで、まだサポートされていない、といえる状態です。 Issue: https://github.com/ruby/zlib/issues/7 実装箇所: https://github.com/ruby/zlib/blob/master/ext/zlib/zlib.c#L3861 RubyGems: https://rubygems.org/gems/zlib/versions/1.1.0 なので、適当に処理するしかないので、こんな感じにします。Rubyは全く書かないので、この実装で良いかは怪しいです。 def uncompress(gzip_data) decoded_data = "" while gzip_data do Zlib::GzipReader.wrap(StringIO.new(gzip_data.b)) do |gz| decoded_data << gz.read gzip_data = gz.unused end end decoded_data end readで1つ分は読めて、unusedに余ったデータが残るので、残ったデータに対してまたreadを繰り返して連結していきます。 雑過ぎますが、テストコードで必要になった実装なので雑でいいんです(いいのか?) zcatが待ち遠しいですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WEBrickを使って動的なhtmlを返す(〜 GETとPOSTの違い 〜)

前回の記事(Webrickを使って静的なhtmlを返す)の続き 前回作ったページ 投稿フォーム 対応するhtml(一部) <h2>GETで送る</h2> <ul> <form action="/form_get" method="get"> <li><label for="user_name">ユーザー名</label> <input type="text" name="user_name"></li> <li><label for="age">年齢</label> <input type="text" name="age"></li> <button type="submit">投稿</button> </form> </ul> <h2>POSTで送る</h2> <ul> <form action="/form_post" method="post"> <li><label for="user_name">ユーザー名</label> <input type="text" name="user_name"></li> <li><label for="age">年齢</label> <input type="text" name="age"></li> <button type="submit">投稿</button> </form> </ul> 今回は、ユーザーが入力した情報に合わせた動的なページを作成する webrick.rbに追記 webrick.rb require 'webrick' server = WEBrick::HTTPServer.new({ :DocumentRoot => './', :BindAddress => '127.0.0.1', :Port => 8000 }) # 以下追記 server.mount_proc("/form_get") do |req, res| # レスポンス内容を出力 x = req.query body = "<html><body><head><meta charset='utf-8'></head><p>クエリパラメータは#{x}です</p></br> <p>こんにちは#{x["user_name"]}さん。あなたの年齢は#{x["age"]}ですね</p></body></html>" res.status = 200 res['Content-Type'] = 'text/html' res.body = body end server.mount_proc("/form_post") do |req, res| # レスポンス内容を出力 x = req.query body = "<html><body><head><meta charset='utf-8'></head><p>フォームデータは#{x}です</p></br> <p>こんにちは#{x["user_name"]}さん。あなたの年齢は#{x["age"]}ですね</p></body></html>" res.status = 200 res['Content-Type'] = 'text/html' res.body = body end server.start 解説 ※ 追記部分の上段がGETリクエストを受けた場合の処理で下段がPOSTリクエストの処理 ※ reqに入るのはWEBrick::HTTPRequest オブジェクトであるため、WEBrick::HTTPRequest クラスのインスタンスメソッドであるqueryメソッドがreqに対して使える。 ※ queryメソッドは、リクエストのクエリーまたはクライアントがフォームへ入力した値をハッシュにして返すメソッド。 つまり、フォームのユーザー名の欄に「太郎」、年齢の欄に「25」と入力した場合、req.queryの返り値は{ "user_name" => "太郎", "age" => "25" }となる (参考:instance method WEBrick::HTTPServer#mount_proc) 入力情報をGETで送った場合とPOSTで送った場合の違い GETリクエストの場合 フォームのユーザー名の欄に「太郎」、年齢の欄に「25」と入力し、『投稿』を押すと、/form_get?user_name=太郎&age=25に対してGETリクエストを送れる。 これを受けたサーバーは「太郎」「25」に対応したhtml、すなわち『こんにちは太郎さん。あなたの年齢は25ですね』というページを返してくれる。 ユーザーの入力に応じて無限に変化可能なページを返せるので、まさに動的なページである POSTリクエストの場合 フォームのユーザー名の欄に「太郎」、年齢の欄に「25」と入力し、『投稿』を押すと、/form_postに対してPOSTリクエストを送れる。 これを受けたサーバーは「太郎」「25」に対応したhtml、すなわち『こんにちは太郎さん。あなたの年齢は25ですね』というページを返してくれる。 もちろんこちらもユーザーの入力に応じて無限に変化可能なページを返せるので、動的なページが実現している GETとPOSTの違い ユーザーがフォームに情報を入力した場合、GETの場合は/form_get?user_name=太郎&age=25というクエリパラメーターが発行されるのに対して、POSTの場合は発行されない。その代わりにPOSTでは、ユーザーが入力した情報はリクエストbodyのForm Dateに格納される
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WEBrickを使って静的なhtmlを返す

WEBrickを使ってHTMLを返すというのを学習したので、アウトプットしようと思います。 http://localhost:8000/fom.htmlにアクセスして以下の画面が表示されるようにする (1)まずWEBrickというライブラリを使ってWebサーバーを構築する webrick.rbファイルを作成し以下のコードを記述 webrick.rb require 'webrick' server = WEBrick::HTTPServer.new({ :DocumentRoot => './', :BindAddress => '127.0.0.1', :Port => 8000 }) 解説 ・ require 'ライブラリ' :外部ライブラリを読み込むメソッド ・server = WEBrick::HTTPServer.new():newメソッドでWEBrick::HTTPServerクラスからインスタンスを作り、返り値をserverに代入する。 ・:DocumentRoot => './', :アクセス先はhttp~~/ ・:BindAddress => '127.0.0.1' :127.0.0.1は自分のパソコンにアクセスできる特別なipアドレス ・:Port => 8000 :ポート番号8000番 (2)次にHTMLの作成 WEBrickはデフォルトで同一ディレクトリにあるindex.htmlファイルをレスポンスとして返す。なのでwebrick.rbファイルがあるディレクトリにform.htmlディレクトリを作り、そこにindex.htmlを入れる。 これでhttp://localhost:8000/fom.htmlにアクセスしたときにindex.htmlが返ってくる form.html/index.htmlに以下を記述 index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h2>GETで送る</h2> <ul> <form action="/form_get" method="get"> <li><label for="user_name">ユーザー名</label> <input type="text" name="user_name"></li> <li><label for="age">年齢</label> <input type="text" name="age"></li> <button type="submit">投稿</button> </form> </ul> <h2>POSTで送る</h2> <ul> <form action="/form_post" method="post"> <li><label for="user_name">ユーザー名</label> <input type="text" name="user_name"></li> <li><label for="age">年齢</label> <input type="text" name="age"></li> <button type="submit">投稿</button> </form> </ul> </body> </html> 解説 action 属性は、フォームで収集したデータを送信すべき場所 (URL) を定義します method 属性は、データを送信するために使用する HTTP メソッド ( get または post ) を定義します name 属性は、送るデータの名前(サーバーはその名前で受け取る)  value属性は、入力された値が入る これは、単なる静的なページを返している(HTMLの限界) 次回Rubyを使って投稿者ごとに異なるページを返すプログラムを作る(動的ページの作成)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#1.5 ユーザー編集機能

はじめに 自己学習復習シリーズの#1.5になります。 自己学習の為に記事作成しております。 この記事が誰か1人の役に立ったら幸いです。 今回はユーザー編集機能編です。 ユーザー編集機能作成においてすべき事 users controllerにてeditアクション、updateアクションの作成&ストロングパラメーターの作成 routes.rbにてルーティングの作成 views/usersにedit.html.erbを作成し、編集フォームを作成 マイページや編集ページに遷移できるようにリンクを作成する 以上の4点を行えば、ユーザー編集機能の実装を終える事ができる。 今回は丁寧に、 (1)ルーティングの作成(editとupdate/routes.rbにて)。 (2)editアクションの記述(users controllerにて)。 (3)edit.html.erbにて編集フォームを作成。 (4)updateアクションの記述(users controllerにて)&ストロングパラメーターの作成。 (5)マイページと編集ページにリンク作成。 の順で説明していきます! (1)ルーティングの作成 routes.rb resources :users, only: [:show, :edit, :update] resourcesで作成しているので、そこにeditアクションとupdateアクションのルーティングを作成。 (2)editアクションの記述 users_controller.rb def edit @user = User.find(params[:id]) end (3)edit.html.erbにて編集フォームを作成 users/edit.html.erb <h3><%= @user.name %>さんの編集画面</h3> <%= form_with model:@user, local: true do |f| %> <%= f.label :"名前" %> <%= f.text_field :name %> <%= f.label :"自己紹介" %> <%= f.text_field :introduction %> <%= f.label :"ステータス" %> <%= f.text_field :status %> <%= f.label :"画像" %> <%= f.file_field :image %> <%= f.submit '編集する' %> <% end %> form_withを用いて編集フォームを作成する。 ちなみにこの記述の状態だと、横並びのフォームになっている。 ーーーーーーー以下参考写真ーーーーーーーーーー ーーーーーーーーーーーーーーーーーーーーーーー (4)updateアクションの記述&ストロングパラメーターの作成 users_controller.rb def update @user = User.find(params[:id]) @user.update(user_params) redirect_to user_path(@user) end deviseによって作成されたuserなので、 user_controller.rbにcreateの時に作成されたストロングパラメーターが存在しない。 なので、private内にストロングパラメーターを記述する。 users_controller.rb private def user_params params.require(:user).permit(:name, :image, :introduction, :status) end (5)マイページと編集ページにリンク作成 今のままだと編集ページに遷移できない&編集ページからは編集しないと戻れないので、、 users/show.html.erb : : <%= link_to '編集する', edit_user_path(@user) %> users/edit.html.erb : : <%= link_to 'マイページへ戻る', user_path(@user) %> 最後に 以上でユーザー編集機能の実装が終わりました。 ユーザー編集機能は慣れたら簡単だと思うので、復習を重ねて早く慣れましょう!! 今回も見てくださった方はありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby]モジュールについて

はじめに 本記事では、モジュールについて記述します。 モジュールとは モジュールは、機能を1つずつ分けて他のファイルから読み込めるようにした処理のまとまりのことです。 module A def A_method "A_method" end end class B include A def B_method @B = 2 end end object = B.new object.A_method moduleAをclassBにincludeすると、 moduleAに含まれているメソッドをclassBのインスタンスが使えるようになります。 ``` 「流れ」 object ↓クラスへの参照 クラスB ↓include モジュールA というような探索の流れになります。 クラスが複数のモジュールをincludeした場合 module A def A_method "A_method" end end module B def B_method "B_method" end end class C include A include B def C_method @C = 3 end end object = C.new object.A_method 「流れ」 object ↓クラスへの参照 クラスC ↓include モジュールB ↓include モジュールA というような探索の流れになります。 探索の順番として、最後にincludeしたモジュール(ここではB)から探索します。 prepend prepend = 「追加する」 by Google先生 追加するという形なので、 includeとはまた違う探索の流れになります。 module A def A_method "A_method" end end class B prepend A def B_method @B = 2 end end object = B.new object.A_method 「流れ」 object ↓クラスへの参照 モジュールA ↓クラスへの参照 クラスB ↓prepend モジュールA というような探索の流れになります。 複数のモジュールをprependする場合。 module A def A_method "A_method" end end module B def B_method "B_method" end end class C prepend A prepend B def C_method @C = 3 end end object = C.new object.A_method 「流れ」 object ↓クラスへの参照 モジュールB ↓クラスへの参照 モジュールA ↓クラスへの参照 クラスC ↓prepend モジュールA ↓prepend モジュールB というような探索の流れになります。 prependもincludeと同様に、後にprependしたモジュールBから先に探索される。  以上です。 終わりに 基礎の部分の定着のために、 明日は、基本情報技術者試験のテキストで学習しようと思います。 以下参考サイトです。 Rubyのmoduleの使い方とメリットを理解して脱初心者! 【ruby】 メソッド探索から見る、モジュール・特異メソッド・特異クラス 明日も頑張ります!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む