rails永遠の初心者の備忘録

物忘れの激しい経営者による備忘録

ajaxでファイルを扱うとActionController::InvalidAuthenticityTokenになる件について

railsajaxで、ファイルをcreateしようとしたら、ActionController::InvalidAuthenticityTokenとでて進まなくなりました。結論からいうと、下記のURLを参考にgemをbundle installしたら解決しました。

RailsでファイルアップロードをAjaxでする時 | Kntmrkm.new()

github.com

解決策

remotipartというgemをbundle installしたら解決しました。詳しいことはぜんぜんわかっていません。。。

github.com

取りあえずこれで解決したので、よしとします。

お問い合わせに迷惑メールが大量にきたので、「SimpleCaptcha2」で画像認証を導入した

設置しているサイトのお問い合わせフォームに死ぬほど大量に迷惑メールがきたので対処方法として画像認証を導入しました。

github.com

導入

導入は対して難しくなかったです。上記で紹介したgithubの手順通りにやったら簡単にできました。手順は以下の通りです。

1.ghostscriptを導入

ghostscriptってやつのインストールが必要らしいので、brewを使ってインストール。rvmを使っている人はrvmでインストールするんでしょうか。この辺はイマイチわかっていません。

brew install ghostscript

2.gemfileに記述してbundle install

gemfileに下記を記述してからターミナルでbundle installします。

/Gemfile

gem 'simple_captcha2', require: 'simple_captcha'
bundle install

インストールは素直にやってくれました。

3.migrationファイルを精製してrake db:migrate

simple_captchaを使うためにデータテーブルを精製してmigrateします。

rails generate simple_captcha [template_format]
rake db:migrate 

4.application_controllerにsimple_captchaをincludeする(controllerベースの場合)

simple_captchaを使えるようにするために、コントローラーにincludeします。ちなみにsimple_captchaはmodelベースでも使えるみたいで、modelベースで使いたい場合はmodelに記述することもできます。その場合はapplication_controllerに書く必要はなく該当するmodelに書けばいいみたいです。今回はお問い合わせフォームというmodelに紐づかないものに対して画像認証を入れたかったのでcontrollerに書きました。

/controllers/application_controller.rb

include SimpleCaptcha::ControllerHelpers

5.controllerに画像認証できた場合と出来なかった場合のロジックを書く

画像認証が出来た場合と出来なかった場合のロジックを書いてあげます。

/controllers/hoge.rb

if simple_captcha_valid?
  #画像認証が通った場合の処理を書きます。今回はお問い合わせありがとねというメールを自動返信します。
else
  #画像認証が通らなかった場合の処理を書きます。画像認証間違ってるよってメッセージをflashで出します。
end

6.viewに画像認証を表示させる

/views/hoge.html.erb

<%= show_simple_captcha %>

7.日本語化のためにlocalsのja.ymlを編集

日本語化しているので、下記を指定してあげないと、translation missingが表示されちゃうので、指定してあげます。

/locals/ja.yml

ja:
  simple_captcha:
    placeholder: "画像の文字を入力してください"
    label: "画像認証"
    refresh_button_text: "Refresh"

これでばっちり動きました。めでたし、めでたし。

迷惑メールはどうなった?

画像認証を導入してからぱたりと迷惑メールはとまりました。一方でユーザーさんのお問い合わせに一手間かかることになってしまったのでもっといい対策があれば、そっちも検討しようと思います。何か迷惑メールのよい対処法があれば教えてください!

Paperclipを使って画像をコンソール経由で保存するやり方

まあこのページの通りですが、英語ばかりで日本語がなかったのでメモとしてまとめておきます。

github.com

僕がやりたかったのは既にあるproductデータのimageに画像を入れたかったので、リンク先の通りのcreateではなく下記の通り、update_attributesでやってます。下記ではProductの一番最初のデータ(first)のものにjpegのimageを挿入するって処理になってます。

Product.first.update_attributes(image: File.open("/~~~~/***.jpeg"))

File.openの後は普通に画像があるパスを指定してあげればOK。Macを使ってるのであればパスの見方は下記リンク先を参照。初心者にはパスを指定してあげるってのも辛かったりするので。。。

book.mynavi.jp

さくらVPS設定の手順の備忘録

さくらVPSで新規サービスを立ち上げたので、その備忘録です。基本的にはドットインストールを参考にしていますが、だいぶ古くなってきたので新しく参考にした方がよいかもしれませんね。

さくらのVPS入門 (全21回) - プログラミングならドットインストール

1.サーバーの起動

サーバーを起動させます。これはボタンをポチッと押すだけなので簡単です。さくらVPSのデザインが変わって管理画面がフラットデザインになっていますね。

2.sshログイン

サーバーを起動後、sshでログインしようとしましたが、すぐには立ち上がらないのか、エラーがでてしまいました。

ssh root@サーバーIPアドレス
=> #ssh: connect to host サーバーIPアドレス port 22: Connection refused

こちらのサイトによると、再起動するのがよいみたいなので、再起動したらすんなりsshでログインができました。

さくらVPSに申し込んでみる - yk5656 diary

3.日本語化

sysconfigのi18nの設定を変更して日本語対応にします。

vim /etc/sysconfig/i18n
=> LANG=“ja_JP.UTF-8"   ## "C"を"ja_JP.UTF-8"に変更

4. 作業用ユーザーの追加

作業用ユーザーを追加します。

useradd [ユーザー名]
passwd [ユーザー名]
usermod -G wheel [ユーザー名]
visudo

=> %wheel  ALL=(ALL)       ALL #コメントアウトして有効化する

5. 鍵認証の追加

パスワードではなく、公開鍵によるログインに変更してセキュリティを高めます。

mkdir ~/.ssh   #ssh用のディレクトリを作成
chmod 700 ~/.ssh  #権限を700に変更

ローカルのパソコンで作業

scp ~/.ssh/id_rsa.pub [ユーザー名]@[サーバーIPアドレス]:~/.ssh/authorized_keys
#公開鍵をauthorized_keysという名前で転送する

公開鍵を転送したら、パスワードなしでログインできることを確認する

ssh -i ~/.ssh/id_rsa  [ユーザー名]@[サーバーIPアドレス]

6.SSHの設定を行う

次にsshの設定を行って、セキュリティを高める。

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org
#予めオリジナルファイルをコピーして保存しておく

vim /etc/ssh/sshd_config
=> Port 22 #コメントアウトし、任意の番号に変更
=> PasswordAuthentication no #yesをnoに変更
=> PermitRootLogin no #yesをnoに変更

service sshd restart
#sshを再起動する

これでPort番号が任意の番号に変更され、パスワードでのログインが不可能になり、rootでのログインも不可能になってセキュリティが高まる。

7.ファイアーウォールの設定

vim /etc/sysconfig/iptables
#ファイアーウォールの設定ファイルを作成

=>
*filter
:INPUT          DROP    [0:0]
:FORWARD        DROP    [0:0]
:OUTPUT         ACCEPT  [0:0]
:SERVICES       -       [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -j SERVICES
-A INPUT -p udp --sport 53 -j ACCEPT
-A INPUT -p udp --sport 123 --dport 123 -j ACCEPT
-A SERVICES -p tcp --dport [先ほど設定したポート番号] -j ACCEPT
-A SERVICES -p tcp --dport 80 -j ACCEPT
-A SERVICES -p tcp --dport 443 -j ACCEPT
COMMIT
service iptables start
#iptablesを再起動

8.webサーバーの設定

apacheをインストールして、webサーバーの設定を行う。

yum install httpd
#httpdのインストール

chkconfig httpd on
#httpdの自動起動を設定

cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
#設定ファイルをコピーしておく

vim /etc/httpd/conf/httpd.conf
#設定ファイルの変更

=> ServerTokens Prod #OSをProdに変更
=> ServerSignature Off #OnをOffに変更
=> ptions -Indexes FollowSymLinks #Indexesの前に-を入力

service httpd configtest
#文法テスト、OKが出力されたら問題なし

service https start
#再起動して設定を反映させる

9.mysqlの設定

yum install mysql-server
#mysqlのインストール

cp /etc/my.cnf /etc/my.cnf.org
#設定ファイルのコピー

vim /etc/my.cnf
#設定ファイルに以下を追記する

character_set_server=utf8
default-storage-engine=InnoDB
innodb_file_per_table
[mysql]
default-character-set=utf8
[mysqldump]
default-character-set=utf8

service mysqld start
#再起動する

mysql_secure_installation
#mysqlのセキュリティ設定を強化する

chkconfig mysqld on
#mysqlの自動起動を設定する

mysql -u root -p
#先ほど設定したパスワードでログインできるか確認する

10.Ruby on Railsのインストール

sudo yum install zlib-devel openssl-devel sqlite-devel
#必要ファイルをインストールする

curl -L https://get.rvm.io | bash -s stable
#rvmをインストールする

source /home/[ユーザー名]/.rvm/scripts/rvm
#rvmを起動する

rvm install [version]
#rubyのインストール

gem instal --no-ri --no-rdoc sqlite3
#sqlite3のインストール

curl -sL https://rpm.nodesource.com/setup | bash -
yum install -y nodejs
#node.jsのインストール

gem install rails --version "=4.1.4”
#railsをインストール、今回はversionを4.1.4で指定してインストール

node.jsのインストールは下記を参照

Installing Node.js via package manager · joyent/node Wiki · GitHub

最後に

いつもやってる作業だけどまとめておくと今後便利かもということでまとめておく。毎回、ドットインストール見るのも大変だし。

lazy_high_chartsで毎日のユーザー登録数をグラフ化する

前回のメモの続きです。

railsで日ごとの登録ユーザー数を取得する方法 - rails永遠の初心者の備忘録

日にちごとに取得したユーザー登録数をかっこよくグラフ化してわかりやすくしました。前回も紹介したこのブログを参考にしています。

RailsでHighcharts(lazy_high_charts)を使って綺麗なグラフを描画する - nishio-dens's diary

lazy_high_chartsをrailsに導入する

gemにあるので、gemfileに書いて、bundle installするだけです。

/gemfile

gem 'lazy_high_charts'

javascriptを有効にするために、application.jsに以下の三行を追加します。 /app/assets/javascript/application.js

//= require highcharts/highcharts
//= require highcharts/highcharts-more
//= require highcharts/highstock

gemをインストールしたらサーバーを再起動するのを忘れずに。1年ぐらい前はサーバーの再起動をせずにはまって三日放置とかよくしていました。。。

lazy_high_chartsでグラフを書く

導入できたらグラフを書いてもらいます。グラフを書くには、x軸のデータとy軸のデータがそれぞれ配列になっている必要があります。前回の記事に書いた通り、x軸になる日付のデータと、y軸のユーザー登録数を下記のコードで取得しています。

/app/controllers/charts_controller.rb

days = (Date.today.beginning_of_month..Date.today).to_a
#後々、usersとtransposeする予定なので、rangeではなく、arrayに変更

users = days.map { |item| User.where(:created_at => item.beginning_of_day..item.end_of_day).count }
#mapでそれぞれの日にちに登録されたユーザー数をカウント

これにチャートを書くコードを追加すれば完成です。

/app/controllers/charts_controller.rb

days = (Date.today.beginning_of_month..Date.today).to_a
#後々、usersとtransposeする予定なので、rangeではなく、arrayに変更

users = days.map { |item| User.where(:created_at => item.beginning_of_day..item.end_of_day).count }
#mapでそれぞれの日にちに登録されたユーザー数をカウント

@graph = LazyHighCharts::HighChart.new('graph') do |f|
  f.title(text: "月間登録推移")
  f.xAxis(categories: @daily_days)
  f.series(name: '登録数', data: @daily_counts)
end

これだけで完了です。これだけで結構きれいなグラフをポンと書いてくれます。今度は円グラフやら、色んなタイプのグラフに挑戦しようと思います。

railsで日ごとの登録ユーザー数を取得する方法

毎日どれだけユーザーが増えたかは非常に大事な要素で、毎日データを追っていますが、ぶっちゃけ今までは手集計してエクセルに放り込むというあり得ない運用をしていました。リニューアル用のコードを書くのを機にそういった非効率を改めようとコードを書こうとしたら思いのほか手間取ったのでメモ。

今回はこちらのサイトを参考にさせてもらいました。

RailsでHighcharts(lazy_high_charts)を使って綺麗なグラフを描画する - nishio-dens's diary

配列からハッシュを作成する - ハッシュ(Hash)クラス - Ruby入門

目次

・月初から今日までの日にちを取得

・日にちごとのユーザー登録数を取得

月初から今日までの日にちを取得

railsではactive_supportのおかげで、日にちの取得がだいぶ楽になっているようなのでありがたく使わせてもらいます。

Date.today.beginning_of_month

こう書くだけで、今月の月初の日にちが取得できます。 同様に

Date.today.end_of_month

これで月末の日にちが取得できるみたいです。便利。 最終的に今日までの日にちが欲しいので、

Date.today.beginning_of_month..Date.today

として日にちは完了。

日にちごとのユーザー登録数を取得

これに結構手間取りました。悩んだ末にmap使って取得するようにしました。

days = (Date.today.beginning_of_month..Date.today).to_a
#後々、usersとtransposeする予定なので、rangeではなく、arrayに変更

users = days.map { |item| User.where(:created_at => item.beginning_of_day..item.end_of_day).count }
#mapでそれぞれの日にちに登録されたユーザー数をカウント
#ここでも、active_supportのbeginning_of_dayとend_of_dayを利用

これで欲しかった日ごとのユーザー登録数が取得できました。もっとうまいやり方がありそうだけど、取りあえずこれで動きそうなので動かします。

Rails4+devise 複数のdeviseモデル対応

今日からメモ的に残していきます。rails3のプロジェクトをrails4に変更している中で、devise対応で手間取ったのでそのメモになります。

Rails の認証プラグイン Devise での Strong Parameters について | EasyRamble

今回はこちらのブログを主に参考にさせてもらいました。

目次

Userモデルに加えて、Editorモデルも作りたい場合の対応についてのメモです。

複数viewの対応(config.scoped_views = true)

複数モデルのStrongParameters対応

複数viewの対応(config.scoped_views = true)

deviseで複数viewを有効にするには、下記を追加。これをやらないでおくと、例えばEditorモデルのconfirmationメールを送って欲しいのにも関わらず、デフォルトの/devise/mailer/confirmation_instructions.html.erbが送られてしまったりして厄介。

/config/initializer/devise.rb

config.scoped_views = true

複数モデルのStrongParameters対応

これに結構はまりました。rails4からStrongParametersというものが導入され、modelとcontrollerの記述が大きく変わっています。deviseでは若干やっかいな対応が必要で、冒頭の方のブログを読ませてもらい、ドキュメントを見ながら対応しました。

plataformatec/devise · GitHub

ドキュメントと冒頭のブログを読むと、下記のコードを追記すればいいっぽいのですが、どこに書けばいいのかわからず、右往左往。

class User::ParameterSanitizer < Devise::ParameterSanitizer
  def sign_in
    default_params.permit(:username, :email) #追加したいパラメータ
  end
end

githubで検索すると/libの直下にuser_sanitizer.rbとして保存しているアプリが多いのですが、やってみてもうまくいきませんでした。(深く調べてません。。。)ということで、よくわからないけど、/model/user.rbの下に下記のような形で追記したらうまく動いたのでよしとしました。

/app/models/user

class User < ActiveRecord::Base
  #様々なコード
end

class User::ParameterSanitizer < Devise::ParameterSanitizer
  def sign_in
    default_params.permit(:username, :email) #追加したいパラメータ
  end
end

まとめと反省

sanitizerについてはどうなっているのかよく調べておきたいところ。なぜ他のアプリでは/lib直下に置いているのか、なぜこちらの環境では動かなかったのか、この二点についてはわかり次第、追記したいと思います。(教えてくれる人も歓迎です。)