読者です 読者をやめる 読者になる 読者になる

google analytics をrailsで使う方法

まず以下のgoogleサイトでトラッキングidを取得。 www.google.com

Gemfileに

gem 'google-analytics-rails'

を追加してbundle install

config/environments/production.rbに

# トラッキングIDを記す
GA.tracker = "UA-xxxxxx-x"

view/layout/application.html.slimのhead内に

= analytics_init if Rails.env.production?

とした後にデプロイ!!

アナリティクスの専用ページに戻って、リアルタイム状況などで稼働していれば成功!!

最近使っていて便利だと思ったtryメソッド

これを初めて使った時率直にすげえーと思いました。今後使うことも多くなるだろうなと思い備忘録として簡単にまとめておきます。

try はメソッドが nil でなければ指定したメソッドを呼び出します。

例えば、よくありがちなuser.email としたいときに user.try(:email) みたいにして使います。

思い返してほしいのですが、 user.email としたときに email が nil の場合でuser.nilと成ってしまい、NoMethodErrorが出てしまうことって多々あると思うのですが。 Object#try メソッドを使えば華麗にこの問題を回避することができます。

tryメソッドのコード例

user.try(:email) || '本来はnil'

=>emailが存在する時にはuser.emailとなり,userがnilの場合は'本来はnil'と表示されます。

参考//www.techscore.com

ActionMailer 使い方

  1. いきなりメール設定をしていく(今回はgmailを扱う前提)

    config/environments/development.rb

  config.action_mailer.raise_delivery_errors = true ← メールでエラーが出た時にログを出してくれる
  host = 'localhost:3000'
  config.action_mailer.default_url_options = { host: host}
  #mail設定

  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'gmail.com',
    user_name: 'hogehoge@gmail.com',     ←gmailにログインする時のアドレス
    password: 'gmailのpassword',
    authentication: 'plain',
    enable_starttls_auto: true
  }

ActionMailerクラスを生成する

$ rails g mailer notice_mailer send_event_participation(←メソッド)     で以下のファイルができるのでそれぞれいじっていく

app/mailers/notice_mailer.rb app/mailers/application_mailer.rb app/views/notice_mailer/send_event_participation.html.slim    app/views/notice_mailer/send_event_participation.text.slim   spec/mailers/notice_mailer_spec.rb

spec/fixtures/message/send_event_participation

spec/mailers/previews/notice_mailer_preview.rb

3. メールの共通設定をするapplication_mailer.rbをいじる

class ApplicationMailer < ActionMailer::Base# 全メーラーの共通設定
  default from: "noreply@example.com",
          bcc:      "sample+sent@example.com",
          reply_to: "sample+reply@example.com"
  #####layout 'mailer'  ← template errorが出たりしたらコメントアウトしてください
end

4. notice_mailer.rbをいじる

class NoticeMailer < ApplicationMailer
  #イベントに参加した時に詳細をメールで送信する

  def send_event_participation(user, reservation)
    @user = user
    @event = Event.find(reservation.event_id).title
    mail to: user.email,
         subject: 'イベントに参加しました!'
  end
end

5. コントローラー側にメールを送信するタイミングを記述 reservation_controller.rbのcreateメソッドで使います(イベント予約の受付をメールで確認するイメージ)一例

def create
    reservation = Reservation.find_or_initialize_by(user_id: current_user.id, event_id: params[:id])
    if reservation.save
      NoticeMailer.send_event_participation(current_user, reservation).deliver_now #メール送信部
      redirect_to event_path(params[:id]), :flash => { :success => '参加予約完了しました!'}
    else
      flash.now[:error] = 'すでに参加済みです'
      redirect_to event_path(params[:id])
    end
  end

6.メソッド名に関連したsend_event_participation.html.slimにメールの内容を書く

p #{ @user.name }さんこんにちは!
p #{ @event }のイベントに参加受付を完了しました。

これで送信受信が正常にできるはず!!!!!!!

本番環境でのメール送信

上記の設定のままheroku環境でメールを送信したところ見事にエラー発生... 当たり前だが本番用の設定をする必要がある。 production環境からメール送信するために、「SendGrid」を使用する。

$ heroku addons:create sendgrid:starter ← アドオンをアプリに追加する

続いて、config/environments/production.rb内を設定していく

config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  host = '[herokuのサブドメインを入力].herokuapp.com'
  config.action_mailer.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    :address => 'smtp.sendgrid.net',
    :port => '587',
    :authentication => :plain,
    :user_name => ENV['SENDGRID_USERNAME'],
    :password => ENV['SENDGRID_PASSWORD'],
    :domain => 'heroku.com',
    :enable_starttls_auto => true
  }

$ heroku config で環境変数を確認し SENDGRID_USERNAMEとSENDGRID_PASSWORDが設定されていることを確認。

$ git add -A  

$ git commit -m "メール本番環境設定"  

$ git push origin master

$ git push heroku master  

$ heroku run rake db:migrate

でおk!!!!

Action Mailer の基礎 | Rails ガイド

CarrierWave の使い方 by チュートリアル11章

 

CarrierWaveとは画像をアップロードや画像リサイズができるgemのこと

早速実装方法を解説します。

 

1. gemfileに

    gem 'carrierwave' #アップローダ

    gem 'mini_magick'#リサイズ機能

    gem 'fog'#本番環境に画像をアップする

を追加。 

2. $ bundle install

3. $ rails g uploader Picture #pictureモデルのアップローダーを生成

 

4. $ rails g migration add_picture_to_microposts picture:string   #micropostモデルにpictureカラムを追加

5. $ rake db:migrate

 

6. models/micropost.rbに

 mount_uploader :picture, PictureUploader

 

と一行書き足す。mount_uploaderはメソッドで、赤字部分はアップローダーのクラス名を指していることに注意 。

 

7. viewにアップロードフォームをさくせいする

 _micropost_form.html.erb

(ハイライト部分が書き足したコード)

<%= form_for(@micropost, html: { multipart: true }) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-primary" %>
  <span class="picture">
    <%= f.file_field :picture %>
  </span>
<% end %>

 html: { multipart: true } はファイルをアップロードする際に必要なオプションです

 

 

8. app/controllers/microposts_controller.rb内の

 

strongparamsに:pictureを追加

params.require(:micropost).permit(:content, :picture)

 

9. app/views/microposts/_micropost.html.erb

 マイクロポストの画像表示をするために一行追加

<%= image_tag micropost.picture.url if micropost.picture? %> 

picture? はbooleanを返してくれる。trueなら画像を表示してくれる

 

ここまでで画像投稿と表示はできるようになります。ここから下は画像のリサイズをしていきます。

 

10.  app/uploaders/picture_uploader.rbにバリデーション

 

 def extension_white_list
    %w(jpg jpeg gif png)    #これらの拡張子のみ表示できる
  end

 

11. app/models/micropost.rb 内で画像サイズのバリデーション

(ハイライト部分を新たに記述すること)

class Micropost < ActiveRecord::Base
  belongs_to :user
  default_scope -> { order(created_at: :desc) }
  mount_uploader :picture, PictureUploader
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 140 }
  validate  :picture_size

  private

    # アップロード画像のサイズを検証する
    def picture_size
      if picture.size > 5.megabytes
        errors.add(:picture, "should be less than 5MB")
      end
    end
end

 

12. ファイルサイズをJqueryで確認

app/views/shared/_micropost_form.html.erb

(ハイライト部分が追加したもの)

<%= form_for(@micropost, html: { multipart: true }) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-primary" %>
  <span class="picture">
    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
  </span>
<% end %>

<script type="text/javascript">
  $('#micropost_picture').bind('change', function() {
    var size_in_megabytes = this.files[0].size/1024/1024;
    if (size_in_megabytes > 5) {
      alert('Maximum file size is 5MB. Please choose a smaller file.');
    }
  });
</script>

バリデーションが完成しました。

 

13. 画像のリサイズ 

まずリサイズするために必要なimagemagickをインストールしていく

$ sudo apt-get update
$ sudo apt-get install imagemagick --fix-missing

macユーザーはapt-getが使えないことがあるので、そうなったらapt-getをbrewに変更してみてください。

 

14.  リサイズするためにアップローダーを修正する

app/uploaders/picture_uploader.rb
class PictureUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick process resize_to_limit: [400, 400]

 

400のところは任意で設定できます。

 

ここまででアップロードと画像のリサイズを実装できました!!拍手!!!

 

本番環境でのアップロード(fog)に関しては後日追加していきます。

 

 

最近覚えたものを忘れないように大変雑にまとめていく

#テスト

assert系 →  予期した結果

refute系    → 「〜にならないこと」

 

#FakerでDB上にサンプルUserを生成する

99.times do |n|

 name = Faker::Name.name

 email = "example-#{n+1}@rails.jp"

 password = "password"

 User.create!(

 name: name,

 email: email,

 password: password,

 password_confirmation: password

 ) 

end

 $rake db:migrate:reset

$rake db:seed

でおk。

 

#toggle!メソッド

user.toggle!(:admin)

→ admin属性の状態をfalseからtrueにする

 

#

if !user_signed_in?は

unless user_signed_in?

if not user_signed_in? (推奨されていないらしい)

とも書ける

 

#

'aria-haspopup' => 'true', 'aria-expanded' => 'false'は

aria: { haspopup: true, expanded: false}

と代替できる。(後者の方がスッキリする)

 

#三項演算子

条件式 ? 真の値 : 偽の値

以下と同義

if @user.nil?

  真の値

else

  偽の値

end

 

# sessionのフォーム

= form_for(:session, url: login_path) do |f|

sessionはインスタンスを持たないため、リソースとそれに対応するURLを指定する

 

#クッキーとは情報を保存するもの

 

#sessionとは接続〜切断までの一連の流れ

ログインをnewとcreate

ログアウトはdestroyを用いている

 

#password_digestとは

ユーザの入力したpasswordをそのまま保存するのは危険! ので、passwordを暗号化するもの

migrationファイルの例

def change

 add_column :users, :password_digest, :string

end

 

# DBでmysqlを扱う方法

$ rails new sample_app -d mysql

gem に mysql追加(version指定しないとほぼ落ちる)

$ rake db:create

$ rake db:migrate

これでおk。

 

$ rails db

> show tables;

> select * from users;

> desc users;

> exit

みたいな感じ

 

#git でsshのキーチェーンの設定方法

$ ssh -T git@github.com

赤文字がキーチェーンとなる

clone などする際には

$ git clone  git@github.com:example/example.git

とする。(:の前までがキーチェーンの範囲)

 

 

#メタプログラミング(黒魔術)とは 

Rubyの最大の特徴で、簡単に言うとコードを生成するコードのこと”(かなり奥が深いらしい、抽象的な記法を使ってコードを書くことにより動的にコードを生成する。)

一見コードをみただけでは何を書いてるのかわからないもの、ターミナル上で引数などを指定し、実行されるまで何が出力されるかわからないもの。

 

#低レベルな知識

コンピューターに近いものの知識らしい(Linuxなど)、高レベルな知識は人間に近いものらしい。低レベルな知識によって技術者の差が出る。

 

#grep コマンド (ask-grep)

- ファイルや標準入力から正規表現でマッチする行を探し出すコマンド

- ログファイルの中から特定のログを探し出したり、ソースコードのあるディレクトリで特定のクラス、メソドなどを定義、呼び出しているところを探したりいろいろな目的で使う.

ex) grep "sample" sample.txt

=> sample

 

# 複合キー

複数項目で1セットな主キー

gem ' composite_primary_keys '

例)reservationsに複合キーを持たせる(user_idとevent_idで)

 reservationのmigrationファイル

def change

  create_table :reservations, id: false do |t|

    t.integer :user_id

    t.integer :event_id

    t.timestamps null: false

  end

  execute 'ALTER TABLE reservations ADD PRIMARY KEY (user_id, event_id);'

end

 

その後

$ rake db:migrate(ここで結構エラー出ます、大体がmigrationファイルでだぶってたりするのが原因なので削除したりして作り直したりしました。)

 

mysql> desc reservations;

        +------------+----------+------+-----+---------+-------+

        | Field      | Type     | Null | Key | Default | Extra |

        +------------+----------+------+-----+---------+-------+

        | user_id    | int(11)  | NO   | PRI | NULL    |       |

        | event_id   | int(11)  | NO   | PRI | NULL    |       |

        | created_at | datetime | NO   |     | NULL    |       |

        | updated_at | datetime | NO   |     | NULL    |       |

        +------------+----------+------+-----+---------+-------+

のようにuser_idとevent_idの2つがprimary keyとなる

 

参考

qiita.com

qiita.com

 

シンタックスシュガーについて

qiita.com

備忘録  ||=

チュートリアル8章に登場する以下の文法を完全に理解しようという記事です。

 

def current_user

   @current_user ||= User.find_by(id: session[:user_id]) 
end
#Userオブジェクトそのものの論理値は常にtrueになることです。そのおかげで、@current_userに何も代入されていないとき(nilの時)だけfind_by呼び出しが実行され、無駄なデータベース読み出しが行われなくなります
#。Rubyでは、nilとfalseを除いて、あらゆるオブジェクトの論理値がtrueになるように設計されています。さらにRubyでは、||演算子をいくつも連続して式の中で使用する場合、項を左から順に評価し、最初にtrueになった時点で処理を終えるように設計されています

 

||= を徹底的に理解する。


この「||=」(or equals) という代入演算子Rubyで広く使用されているイディオムであり、先輩に使いまくるから絶対理解しろって言われた、、、

多くのコンピュータプログラムでは、以下のような記法で変数の値を1つ増やすことができます。

x = x + 1


x += 1 のように短縮形が使える

例 $ rails console

>> x = 1
=> 1
>> x += 1
=> 2
>> x *= 3
=> 6
いずれの場合も、●という演算子があるときの「x = x ● y」と「x ●= y」の動作は同じです。

Rubyでは、「変数の値がnilなら変数に代入するが、nilでなければ代入しない (変数の値を変えない)」という操作が非常によく使われます。or演算子||を使用すれば、以下のように書くことができます。

>> @foo
=> nil
>> @foo = @foo || "bar"
=> "bar"
>> @foo = @foo || "baz"
=> "bar"
nilの論理値はfalseになるので、@fooへの最初の代入「nil || "bar"」の評価値は"bar"になります。同様に、2つ目の代入「@foo || "baz"」("bar" || "baz"など) の評価値は"bar"になります。Rubyでは、nilとfalseを除いて、あらゆるオブジェクトの論理値がtrueになるように設計されています。さらにRubyでは、||演算子をいくつも連続して式の中で使用する場合、項を左から順に評価し、最初にtrueになった時点で処理を終えるように設計されている。

上記の演算子をコンソールセッション上で実際に実行して比較してみると、@foo = @foo || "bar"はx = x O yに該当し、Oが||に置き換わっただけであることがわかります。

x = x + 1 -> x += 1
x = x * 3 -> x *= 3
x = x - 8 -> x -= 8
x = x / 2 -> x /= 2
@foo = @foo || "bar" -> @foo ||= "bar"
これで、「@foo = @foo || "bar"」は「@foo ||= "bar"」と完全に等しいことがわかる。

この記法を現在のユーザーのコンテキストで使用すると以下のように簡潔なコードで表現できるようになります。

@current_user ||= User.find_by(id: session[:user_id])

 

なるほど!!

おk!!!

heroku デプロイ 備忘録

heroku ruby ruby on rails プログラミング

2つの自作アプリをherokuデプロイするまでにそれぞれ異なるエラーが続出し手こずったので忘れないようにまとめます。

 

$ heroku login (herokuにログイン)

$ heroku create ex_app12345(ex_app12345という名前で作られます)

$ git add -A

$ git commit -m "heroku deploy"

$ git push heroku master  ←ここで大体エラーが出る

 

1.まずはgemfileを確認する

group :production do
gem 'pg' #herokuはpgを使います
gem 'rails_12factor'
end

⚠︎それまでsqlite3を使っていたらdevelopment環境下に移動すること

 

2. config/application.rbに

config.assets.initialize_on_precompile = false

と記述。

3. environments/production.rb

 config.serve_static_assets = true
config.assets.compile = true

追加。 

 

これでおそらくいけるはず。

 

pushが成功したら

$ heroku run rake db:migrate --app ex_app12345

を実行し

$ heroku open

デプロイ完了!!

 

二つ目のデプロイの時には

pgをbundle installしたときに

 

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby extconf.rb
checking for pg_config... yes
Using config values from /usr/local/bin/pg_config
checking for libpq-fe.h... yes
checking for libpq/libpq-fs.h... yes
checking for pg_config_manual.h... yes
checking for PQconnectdb() in -lpq... no
checking for PQconnectdb() in -llibpq... no
checking for PQconnectdb() in -lms/libpq... no
Can't find the PostgreSQL client library (libpq)
*** extconf.rb failed ***

こんなエラーが出ましたが、、、

 

$ sudo env ARCHFLAGS="-arch x86_64" gem install pg -v '0.18.4'

上記コマンドで治りました!

 

参考

ayumu-homes.hateblo.jp

 

 

後日追記

 

修正を加え再びgit push heroku masterしたところエラーが出た。

 

DEPRECATION WARNING: The configuration option `config.serve_static_assets` has been renamed to `config.serve_static_files` to clarify its role (it merely enables serving everything in the `public` folder and is unrelated to the asset pipeline). The `serve_static_assets` alias will be removed in Rails 5.0.

 

Rails5.0の仕様にするためにconfig/production.rbのconfig.serve_static_assetsをconfig.serve_static_filesに変更しろとのこと

 

cssも変更したので

$ bundle exec rake assets:precompile

をしてから

$ git add -A

$ git commit -m "deploy heroku"

$ git push heroku master

でいけます。

 

 

2016/5/26日追記

 

dbをpgではなくmysql2でherokuデプロイする方法

 

既にRailsのアプリがあることが前提とpgでデプロイしたことがある方向けに書いてありますので何卒よろしくお願いします。pgでもデプロイもしたことがない方は上部からご覧下さい。どうにかなると思います。
早速database.ymlを下記のようにしておくことで、環境変数で値を設定できるようにしておきます。

# config/database.yml

production:
  adapter:  mysql2   # postgresの場合はadapterをpostgresql
  encoding: utf8
  database: <%= ENV['DB_NAME'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host:     <%= ENV['DB_HOSTNAME'] %>
  port:     <%= ENV['DB_PORT'] %>

 

$ heroku login

$ heroku create ex_name (この場合ex_nameという名前でheroku上に登録される)

 

$git remote -v  でリモートを確認

      heroku https://git.heroku.com/*****.git (fetch)
      heroku https://git.heroku.com/******.git (push)
      origin git@developer.exexex.jp:******/*****.git (fetch)
      origin git@developer.exexex.jp:*****/*****.git (push) 

 

みたいな感じで表示されればおk.

 

次に無料のDBを追加する

$ heroku addons:create cleardb:ignite   

 

HerokuのアプリにDB情報の環境変数を設定する

 

まずは設定を確認

$ heroku config

→ DB接続の書式が表示されるのでそれに従って各環境変数を設定する必要があります

# mysql://[username]:[password]@[hostname]/[db_name]?reconnect=true

 

上の[ ]内に対応させてそれぞれ設定していきます。

 

$heroku config:add DB_NAME="[db_name]"

$heroku config:add DB_USERNAME="[username]"

$heroku config:add DB_PASSWORD="[password]"

$heroku config:add DB_HOSTNAME="[hostname]"

$heroku config:add DB_PORT="3306" #ちなみにpgの場合は5432

 

$ heroku config  で設定を再確認する

この時、恐らくDATABASE_URLがpostgresになっているので、ここもmysql2にする必要がある。これ直さないと後で面倒くさいです。。。)

heroku config:set DATABASE_URL= 'mysql2://[username]:[password]@[host]/[database]?reconnect=true'

 

再再度確認

$ heroku config  

DATABASE_URLのところが mysql2と成っていればおk。

ついでに

Timezoneとlangの設定もしておく

$ heroku config:add TZ=Asia/Tokyo

$ heroku config:add LANG=ja_JP.UTF-8

 

ここでローカルレポジトリをherokuへプッシュ!

$ git push heroku master

$ heroku run rake db:migrate

 

$ heroku open

完了!!


後日新たなエラーが起きました
$ heroku run rake:db migrate
Running rake db:migrate on ⬢ *******app123... up, run.8832
bash: rake:db: command not found   ショック>_<
$heroku run bash --app appname
$rake db:migrate
これで治ります