ActionMailer単体で、HTMLメール送るコードをとにかくすぐ書きたいんです。。
なんというナマケモノでしょう。。
HTMLメールのサンプルを探してぐぐると大抵はもう.html.erbを作っています。
それがもう面倒臭い場合あるいはとにかくHTMLメール送信を試したい場合はこんな調子です。
require 'action_mailer' require 'yaml' require 'erb' conf = YAML.load_file('config.yml') ActionMailer::Base.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'smtp.gmail.com', authentication: :plain, user_name: conf['mailer']['user_name'], password: conf['mailer']['password'], enable_starttls_auto: true } ActionMailer::Base.raise_delivery_errors = true ActionMailer::Base.delivery_method = :smtp class Mailer < ActionMailer::Base default from: 'aaaaaaaaa@bbbbbb.com' def html_mail(to, subject, body) mail(to: to, subject: subject) do |format| format.html { render text: body } end end end Mailer.html_mail('xxxxx@yyyyyyy.com','html mail test', '<b>bold?<b><br /><i>italic?</i>').deliver
一杯書きましたがformat.text
をformat.html
に変えるだけです。。
参考
ActiveRecordでselectしたはずのデータにアクセスできないんです
超はまった。。
priceカラムを持つitemsテーブルがあるとして、商品の日々の価格を記録しているとします。
今日の価格が前日比でどうなったか知るべく、こんな調子のものを書いたとして
q = Item.find_by_sql(<<-SQL) select t1.price - t2.price as price_change from items t1 inner join items t2 on t1.id = t2.id and t2.register_date = 昨日 where t1.register_date = 今日 SQL puts q.first.price_change #=> nil
なんでや。。なんでnilなんや。。
そう、priceというカラムが既に存在するので、select句に書いた列別名price_changeに対しておそらくActiveRecordのattribute_changeが先に利いているものと思われます。
上の例でputs q.first.attributes
するとちゃんとprice_changeが存在するので、おそらくそっちのせいでしょう。
列別名を別にしてあげればうまく差額を返してくれます。私はfluctuationに変えましたよ。。
今回はSELECT文の列別名のネーミングがActiveRecordの作法に合わなかっただけですが、既存のテーブルが似たような有様の場合は要注意ですね。
わざわざ列別名を用意してあげるとか、その列だけattributes[attr]
って調子でアクセスするとか。scopeをうまく使えば何も気にしなくても良くなるのかな?
ActionMailerとERBを単体で使ってRailsみたいにメールを飛ばしたいんです
もうrails使えよみたいな。。
require 'yaml' require 'action_mailer' require 'erb' conf = YAML.load_file('config.yml') ActionMailer::Base.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'smtp.gmail.com', authentication: :plain, user_name: conf['mailer']['user_name'], password: conf['mailer']['password'], enable_starttls_auto: true } ActionMailer::Base.raise_delivery_errors = true ActionMailer::Base.delivery_method = :smtp class Mailer < ActionMailer::Base default from: aaaaaaaa@bbbbbbb.com def notice(to, subject, body) mail(to: to, subject: subject) do |format| format.text { render text: body } end end end Mailer.notice('xxxxxx@yyyyy.com', 'subject', ERB.new(DATA.read, nil, '-').result(binding)).deliver __END__ 本日 <%= Time.now.strftime('%F') %> の買い物リスト <%- ['きのこの山', 'GTA5'].each do |item| -%> ・<%= item %> <%- end -%>
前回のActionMailer使用例のuser/passをyamlから取ってくるように変えました。
yamlは単体で使うとシンボルでアクセスできないんですね。。
railsで.html.erbを書く時、<%- -%>
と書けばその行の行頭空白・行末改行をトリムしてくれましたが、erbを単体で書く場合はERB.newの引数でtrim_modeに'-'を明示しなければいけません。
またActionMailerでメールを投げるメソッド名にはルールというか予約名があるかもしれません。ちゃんと調べていませんが、上記のMailer.noticeは最初Mailer.sendという名前にしていまして、このとき引数toに渡したメールアドレス文字列をなぜかメソッド名として解釈されてしまい何度もmethod missingエラーをもらいました。
D:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/actionmailer-3.1.0/lib/action_mailer/base.rb:455:in `method_missing': undefined method `xxxxx@yyyyyyy.com' for Mailer:Class (NoMethodError)
こんな調子のエラーです。メソッド名をsendddとかにしたらエラーが出なくなったので、メソッド名が悪いのかと。
2013/10/13訂正 これは単にObject#sendを呼んでしまっているんでしょうね。。オーバーライドできていないのは私が基本的なことをわかっていないからでしょう。うう。。
参考
ActionMailer単体でメールを送信したいんです
require 'action_mailer' ActionMailer::Base.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'smtp.gmail.com', authentication: :plain, user_name: '俺のメール', password: '俺のパスワード', enable_starttls_auto: true } ActionMailer::Base.raise_delivery_errors = true ActionMailer::Base.delivery_method = :smtp class HelloMailer < ActionMailer::Base default :from => 'hogehoge@sample.com' def createMessage(to, subject, body) mail(:to => to, :subject => subject) do |format| format.text { render :text => body } end end end HelloMailer.createMessage('宛先@gmail.com', 'hello', 'こんにちは、世界!').deliver # => Net::SMTPAuthenticationError: 534-5.7.9 Application-specific password required. Learn more at
なんでや。。Application-specific password?
そうだった、Googleアカウントは2段階認証にしてたんだった。
Googleのアプリケーション固有パスワードを作成してsmtp_settingsに設定したらうまく送信できた。
参考
- takeisa memo: [Ruby]Rails3.2のAction Mailer単体でメールを送信する
- ActionMailer Railsアプリからメールを送信 - 酒と泪とRubyとRailsと
- GMailのSMTPサーバをRedmineで使う - r-labs
実はそもそもSMTPとかPOPとかよく知らない状態だったので。。
sqlite3初心者のテキトーなメモ
ヘルプ
sqlite3 -help
か、sqlite3実行後に.help
DBファイルを作る
PS$sqlite3 .\practice.db SQLite version 3.7.3 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .databases seq name file --- --------------- ---------------------------------------------------------- 0 main C:\hoge\piyo\fuga\practice.db sqlite>
.databases
ってやると0バイトのこのファイルが生成される。何もせずに.exit
だと何も作られない。
テーブル作ってなんかやる
sqlite> create table prac (date_time text); sqlite> .tables prac sqlite> begin; sqlite> insert into prac values('日付 ' || strftime('%Y-%m-%d %H:%M:%S', datetime('now', 'localtime'))); sqlite> select * from prac; 日付 2013-10-06 16:08:42 sqlite>
begin;
しないとトランザクションが始まらない。
begin;
して何か操作するとprac.db-journalというのが作られて、commit;
rollback;
end;
するとなくなる。
endするとcommitされる。
commit/rollbackするとendしなくてもトランザクションが終わる。sqlplusのつもりでやってはいけない。
データをファイル出力する
select文の結果が見づらいのでね。
sqlite> .output test.txt sqlite> select * from prac; sqlite>
単にSQL実行結果の出力先を標準出力からファイルに向けただけ。
標準出力に戻すには
sqlite> .output stdout sqlite> select * from prac; 日付 2013-10-06 16:08:42 sqlite>
select文の結果を見やすくする
はじめからこれが出来ていればいいんですよ。。
sqlite> .header on sqlite> .mode column sqlite> .width 30 sqlite> select * from prac; date_time ------------------------------ 日付 2013-10-06 16:08:42
カラム幅をいちいち指定しないとデフォルトでぶつ切り表示されてしまうのが困りもの。
sqlite3起動パラメータでも指定可能。
PS$sqlite3.exe -header -column .\practice.db SQLite version 3.7.3 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> select * from prac; date_time ---------- 日付 2013-
カラム幅は指定できません。。
外部ファイルに記述したSQLを実行する
sqlite> .read aiueo.txt date_time ------------------------------ 日付 2013-10-06 16:08:42
alterが貧弱ゥ
alter table hoge add column piyo;
でカラムを追加するか
alter table hoge rename to piyo;
でテーブル名を変更するしかできない。
カラム名を変更したい場合は地道な作業が必要。
って、え。。railsのsqlite3アダプタってマイグレーションでカラム名変える時本当にそんなことやってんの。。
参考
- Query Language Understood by SQLite
- SQLiteのSQL文(テーブルを作成する) | SQLite入門
- .modeコマンド - SQLiteコマンドの使い方 - SQLite入門
- [SQLite] 外部ファイル内のSQLを実行する - Life with IT
- SQLiteでカラム名の変更をする方法 - Hacking My Way ~ itogのhack日記
などなど。
キーボードを掃除したいんです
クッキーばばあの相手をずっとしてました。。
ただいま秒間14億個のクッキーを焼かせていただいております。。Click Frenzyもっとこい。。
キーボードを掃除しました。
参考:キーボードの掃除の仕方について
こちらを参考にしまして。
キートップを洗ったあと渇くのに一晩待つのいやだったし、ドライヤーじゃなかなか渇かなかったので、バスタオルに包み縛って、枕カバーに入れてチャックして、それで乾燥機に放り込みました。洗濯ネットに入れただけだと乾燥機の中でカラカラうるさすぎて近所迷惑になったので。
数分で渇きました。バスタオルや枕カバーも水分吸ってくれたし。
まあそれにしてもキートップ外した後が汚かったのなんのって。埃と抜け毛がすごかったですが、干からびた米もあったし、なにやら小虫の死骸らしきものまで。。
という感じですごくキモかったのでキーボードカバーを買おうとしたら、どうもちゃんとサイズの合うものが全然見つからず……
汚くなるたびに洗うの面倒なので、今度キーボードが汚くなったらカバーとセットで買い換えようかと。リアフォ買ってみようかな。
rubyでcaseを使ってもうちょっといい感じに書けないものかな?
と思っていたら。。
Rubyのcaseを〇〇(言語名)のswitch文だと思っている人たちにぼくから一言ガツンと申し上げたい
つまりこんな書き方が出来る。
obj = 'hoge piyo fuga' other_obj = {} val = begin case obj when nil then 'nilでした' when other_obj then '他といっしょ' when ->p{p.is_a?(Hash)} then 'Hashです' when ->p{p.is_a?(String) && p.split(' ').include?('hoge')} then 'hoge' else 'parse error' end end p val #=> "hoge"
すごいですね-。