Code Serendipity

Keyword: Ruby, Python, javascript, RoR, heroku, AWS...

Code Serendipity

Keyword: Ruby, Python, wordpress, javascript, AWS...

【Rails, ajax】remote:true なリンクでデータベース操作とビューの書き換えをやる【noticeも出す】

f:id:serendipity4u:20170417172047p:plain

基本

  • 前提: users_controller.rbのactivate_userアクションにおいて、ajaxを使う
  • ajaxとは何か:WEBブラウザに実装されているJavaScriptのHTTP通信機能使って、Webページのリロードを伴わずにサーバーとデータのやりとりを行う処理。asynchronous JavaScript + XMLの略。
続きを読む

rails メール一斉送信 #自分用メモ

/tmp/users.csv にデータを出力

SELECT * FROM users INTO OUTFILE ‘/tmp/users.csv’ FIELDS TERMINATED BY ‘,’ OPTIONALLY ENCLOSED BY ‘“’;

一斉送信

 User.all.each do |user|
        MessageMailer.send_diffusion(@message, user).deliver!
      end

管理画面からメール作成、一斉送信

# app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
  def all_notify(users, title, content)
    mail from: 'mail_sender@address.jp'
    mail to: users.map{|u| u.mail}
    mail subject: title
    @content = content
  end
end

# app/view/user_mailer/all_notify.txt.erb

こんにちは
ここから本文--------------
#{@content}
---------------------ここまで

# app/controllers/user_controller.rb メールを送信するコントローラ

# 前略
  def send_to_all
    title = params[:title]
    content = params[:content]
    users = User.all
    UserMailer.all_notify(users, title, content).deliver
  end
# 後略

参考

qiita.com

teratail.com

railsの画像はどこに置くのが良いのか?

どう選ぶのか

結論、assetのコンパイル対象にしたいならassets以下、ブラウザのキャッシュコントロールのためのバージョン管理化に置かれなくていいならpublic以下に置くと良い。 基本的にはシステム側で作る画像はassets以下、ユーザー側のアップロードする画像はpublic配下に置いておくと良い。

だけど、背景画像にしたい時は

public以下に置くようにしている。 気持ち表示速度が速い気がするし、ファイルの書き換えもあまり起こらないと思われるため。 image_urlを使って表示するより、シンプルな気がするため。

先頭に/ スラッシュをつけるとpublic以下になる

<%= image_tag '/images/hoge.png' %>

なら、指定配置場所がpublic/images/hoge.pngだと判断される。

<img src="/images/hoge.png" />
<div style="background-image:url(/images/hoge.png)" /></div>

scssだと

#hoge.css.scss
.hoge {
  background-image: url(/images/hoge.png);
}

参考

Ruby on Rails - Railsで扱う画像はassetsとpublic、どちらに置くといいのでしょうか?(16345)|teratail

Railsアプリをデプロイするとbackground: url(bg-hero-001.jpg)が表示されなくなる話 - Qiita

かんたん自作シェアボタン | Ruby で動的にツイート内容を変える

f:id:serendipity4u:20170417172047p:plain

Ruby で日本語を含む文字列を扱うために、URLモジュールを入れる

ブラウザは、URLにエスケープされた文字列が含まれていた場合それを展開して表示するが、通信するときはエンコードしている。そのため、a href =“"に入れる日本語はエンコードしておく。

続きを読む

delayed_job

githubの重点箇所を英訳。

delayed_job 3.0.0は Rails 3.0以上しかサポートしていないのに注意。

delayed_job を Active Recordで使いたいなら, delayed_job_active_record をGemfileに加える.

gem 'delayed_job_active_record'

Active Record バックエンドはjobsテーブルを必要とする. 以下のコマンドで作成する。

bundle exec rails generate delayed_job:active_record
bundle exec rake db:migrate

.delay.method(params)をどんなプロジェクトでも呼べば、それはバッググランドプロセスとなる。

# delayed_jobなし
@user.activate!(@device)

# delayed_jobあり
@user.delay.activate!(@device)

どんなときでもバックグラウンドでプロセスを走らせたいなら、handle_asynchronously メソッドでデフォルト設定にできる。

class Device
  def deliver
    # long running method
  end
  handle_asynchronously :deliver
end

device = Device.new
device.deliver

パラメータ

handle_asynchronously とdelay は以下のパラメータを利用する:

  • :priority (number): 小さいナンバーほど優先される; デフォルトは0 (例: handle_asynchronously :send_mailer, :priority => 20)

  • :run_at (Time): 指定した秒後に実行する (実行を未来にできる、例:handle_asynchronously :call_a_class_method, :run_at => Proc.new { 2.hours.from_now })

私の環境

すごいシンプルなログインなしセッションでのユーザー情報保存機能【rails】自分用メモ

シチュエーション

  • クイズアプリで、わざわざログインさせたくないけど10分間くらいユーザー情報を保存して(次の問いに繋げるといったことをして)いたい。

  • ECサイトのカートに入れる機能

  • ECサイトのお気に入り機能

  • 投票機能で、同一セッションで多重投票されたくない時

実装レベル

重要度の低い情報を扱うとする(個人情報を含まない)

require "cgi"
require "cgi/session"

cgi = CGI.new
session = CGI::Session.new(cgi,{"new_session"=>false})

コマンドラインでオフラインモードで利用するには

hoge.rb(main):001:0> require 'cgi'
=> []
hoge.rb(main):002:0> cgi = CGI.new
(offline mode: enter name=value pairs on standard input)

# 入力を求められる

hoge=123&fuga=456

#さらにCtrl-D を押すことで続きのプログラムが実行される。


#<CGI:0x007fef6b652ce8
 @accept_charset="UTF-8",
 @accept_charset_error_block=nil,
 @cookies={},
 @max_multipart_length=134217728,
 @multipart=false,
 @options={:accept_charset=>"UTF-8", :max_multipart_length=>134217728},
 @output_cookies=nil,
 @output_hidden=nil,
 @params={"hoge"=>["123"], "fuga"=>["456"]}>

# デフォルトでは、一時ファイル領域のテキストファイルで記録される


session = CGI::Session.new(cgi)

=> #<CGI::Session:0x007fef6ce1a4c0
 @dbman=#<CGI::Session::FileStore:0x007fef6ce1a290 @hash={}, @path="/var/folders/g2/4h5d5fms0qg_3chcnw9s3tm00000gq/T/cgi_sid_3b0a42ee87db63bd">,
 @dbprot=[#<CGI::Session::FileStore:0x007fef6ce1a290 @hash={}, @path="/var/folders/g2/4h5d5fms0qg_3chcnw9s3tm00000gq/T/cgi_sid_3b0a42ee87db63bd">],
 @new_session=true,
 @session_id="bea46c8b0b7e8d8cf29f7647251b5f1f">


session.session_id
=> "bea46c8b0b7e8d8cf29f7647251b5f1f"

cookies

Cookieとは、Webサイトの提供者が、Webブラウザを通じて訪問者のコンピュータに一時的にデータを書き込んで保存させる仕組み。

CookieにはWebサイト(Webサーバ)側が指定したデータを保存しておくことができ、利用者の識別や属性に関する情報や、最後にサイトを訪れた日時などを記録しておくことが多い。ネットサービスなどのサイトで利用者のIDなどが保存されると、次にアクセスしたときに自動的に利用者の識別が行われ、前回の続きのようにサービスを受けることができる。 -IT用語辞典

cookies[:hoge] = { :value => "value", :expires => "30.days.from_now", :path => "/store", :domain => "www.example.com", :secure => true }
  • value ブラウザに保存する文字列。文字列のみが格納できる。
  • expiers クッキーの有効期限。設定をしないと、クッキーをメモリ上で管理しブラウザセッション*1が終了すると削除される。
  • path ブラウザがクッキーを送信するパスを設定する
  • domain ブラウザがクッキーを送信するドメインを設定する
  • secure httpsの時だけクッキーを送信するように設定する (追記)

  • httponly trueにすると、IEFireFoxではJavaScriptcookieを取得できなくなる

session

session[:hoge] = "hoge"
# sessionが多重ハッシュになっている場合、
session[:hoge][:fuga]
# => NoMethodError: undefined method `[]' for nil:NilClass

# `try`はこんな感じで書ける
session[:hoge].try(:[], :fuga)

# 削除する
session.delete(:hoge)

session と cookie を整理

ステートレスなHTTPというシステムの下で、URLでuser id を持たせるのは危険である。なぜなら、URLはクライアント側で改変可能であるから。

そこで、サーバーからクライアント側にsession IDだけ渡して、クライアント側に保持してもらう仕組み(クライアント側に保持してもらう仕組みがcookie)が生まれた。クライアント側がサーバー側にsession IDを渡すと、サーバー側は保持していたユーザー情報をsession IDと照らし合わせて提供する。

参考

yachibit.hateblo.jp

blog.willnet.in

d.hatena.ne.jp