ドラッグアンドドロップで写真をアップロードしてDragonflyで扱いたい on rails
facebookやtwitterのように、ブラウザにドラッグアンドドロップすると自動でアップロードしてプレビュー表示というのをやりたかったので、色々と試してみました。
ドラッグアンドドロップでアップロード
この動作自体はjquery-html5-uploaderというプラグインを使ったら、えらく簡単にできました。
jquery-html5-uploaderのページに書いてある通り、プラグインをロードしてドロップ先のdiv要素とinput要素を用意するだけです。
アップロード先には、Dragonflyのphotoモデルを扱っているphotosコントローラを指定します。
こんな感じです。
$("#image-upload-area, #new_photo").html5Uploader({ name: "dd_file", postUrl: "<%= photos_url %>" });
アップロードされたファイルをDragonflyで扱う
ここではまりました。
photoモデルに紐付いたフォームでアップロードされるわけではないので、いつものように
@photo = Photo.new(params[:dd_file]) # dd_fileは上記javascriptのnameに指定した名前
とやっても、インスタンスを生成できません。
Dragonflyのドキュメントを読んでみると、tempfileオブジェクトからインスタンスを生成できると書いてあります。
最終的には下記の手順で無事写真を登録することができました。
def create if ( params[:dd_file] ) # Dragonflyアプリケーションを生成 app = Dragonfly[:photo] # params[:dd_file].tempfileでtempfileオブジェクトを取り出し、画像ファイルを生成 image_file = app.create(params[:dd_file].tempfile).to_file(params[:dd_file].original_filename) # photoモデルインスタンス生成 @photo = Photo.new # photo modelで定義したアクセッサ(photo_image)に画像ファイルをコピー @photo.photo_image = image_file end respond_to do |format| if @photo.save format.js format.html { redirect_to @photo, notice: 'Photo was successfully created.' } format.json { render json: @photo, status: :created, location: @photo } else format.html { render action: "new" } format.json { render json: @photo.errors, status: :unprocessable_entity } end end end
できてみると簡単なのですが、プレビュー動作も含めるとなんだかんだで2日もかかってしまいました。
[追記] CSRFトークンの追加
うまくいったと思ってよろこんでいたのですが、こんなログが出ていました。
WARNING: Can't verify CSRF token authenticity
jquery-html5-uploader経由だと、CSRFトークンが付かないので怒られているようです。
というわけで、jquery-thml5-uploader.jsに下記2行を追加することにしました。
var csrf_token = $("meta[name=csrf-token]").attr("content"); xmlHttpRequest.setRequestHeader("X-CSRF-Token", csrf_token);
追加した場所は、ファイルの後方で xmlHttpRequest.open("POST", settings.postUrl, true); の直後です。
kaminariでbootstrapのUIを使いたい
ページネーションを導入する必要があったのでググってみたところ、kaminariというのが流行りのようでしたので、kaminariに決定しました。
せっかくなので、bootstrapのUIを使いたい。
githubのドキュメントを読んでみると、kaminariはテーマを変えれば見た目が変わるとのことで、しかもbootstrap用のテーマが用意されておりました。
ドキュメントにしたがってテーマをインストールすると、いつもどおりのエラー終了。
>rails g kaminari:views bootstrap C:/Ruby193p392/lib/ruby/1.9.1/net/http.rb:799:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
でもこれ、見覚えのあるエラーです。
きっと適切なルート証明書が設定されていないのが原因。
Githubのルート証明書をダウンロードして適当な場所に保存。
そのパスをセットします。
※ 証明書のダウンロードの仕方などは、この記事を参考ください。
set SSL_CERT_FILE=c:\cer\github_ca.cer
もう一度テーマをインストール。
>rails g kaminari:views bootstrap downloading app/views/kaminari/_first_page.html.erb from kaminari_themes... create app/views/kaminari/_first_page.html.erb downloading app/views/kaminari/_gap.html.erb from kaminari_themes... create app/views/kaminari/_gap.html.erb downloading app/views/kaminari/_last_page.html.erb from kaminari_themes... create app/views/kaminari/_last_page.html.erb downloading app/views/kaminari/_next_page.html.erb from kaminari_themes... create app/views/kaminari/_next_page.html.erb downloading app/views/kaminari/_page.html.erb from kaminari_themes... create app/views/kaminari/_page.html.erb downloading app/views/kaminari/_paginator.html.erb from kaminari_themes... create app/views/kaminari/_paginator.html.erb downloading app/views/kaminari/_prev_page.html.erb from kaminari_themes... create app/views/kaminari/_prev_page.html.erb
うまくいきました。
\views\kaminariというディレクトリができていますので、さらなるカスタマイズは、その中のファイルをいじると行えます。
Meadowでless mode
bootstrapの設定ファイルはlessで書かれているので、less modeが欲しくなりました。
一番有名そうなless-css-modeが良いかなと思って使おうとしたのですが、ロードするとこんなエラーが出てアウト。
Wrong css-mode.el: please use the version by Stefan Monnier, bundled with Emacs >= 23.
やっぱりWindowsで開発しているからダメなんだと思いつつ、さらにググると別のless-modeを発見。
.emacsはこんな感じ。
(add-to-list 'load-path "~/.emacs.d/less-mode") (require 'less-mode) (autoload 'less-mode "less-mode") (add-to-list 'auto-mode-alist '("\\.less\\'" . less-css-mode))
動きました。
less-css-modeほど高機能ではないようですが、インデントしてくれれば十分なので問題なし。
しかし、セレクタの色もコメントの色も同じでなんだか気持ち悪いです。
コメントはいつもの色じゃないですし。
emacs-lispはよくわからないのですが、当てずっぽうでless-mode.elに下記を加えたらコメントはいつもの色で表示されるようになりました。
(defconst less-css-font-lock-keywords-1 (list ;; 下記行を追記 (list "^[ \t]*\\(//.*\\)+$" 1 font-lock-comment-face)
めでたしめでたし。
関連付けたモデルの属性で、関連元モデルをソートする
【2013.8.10追記】この方法だと所望の結果を得られない場合があります。こちらのエントリも参照ください。
has_manyで関連付けた先のモデルが持っている属性で、元のモデルをソートしたくなりました。
以下のような2つのモデルがあります。
class Spot < ActiveRecord::Base has_many :report end
class Report < ActiveRecord::Base belongs_to :spot end
観光スポット情報を持つspotモデルに、訪問記事であるreportモデルが複数ぶらさがっているイメージ。
それで、登録されているレポートの日付(report.created_at)の新しい順に、spotモデルをソートして取り出したいというのが、今回やりたいこと。
ググってみたところ、逆方向のソートの方法を教えてくれているページがありました。
今回の例だと、reportモデルをspotモデルの属性でソートする方向がそれにあたります。
Railsの事だから逆方向でも大丈夫だろうと思ってやってみたところ、無事成功。
こんな感じで所望の動作をしてくれました。
class Spot < ActiveRecord::Base has_many :report default_scope :include => :report, :order => "reports.created_at DESC" end
毎度、貴重な情報を共有くださっている皆様に感謝です。
サムネイルが2段目からずれる Twitter Bootstrap
※ [追記] 以下、IEでは動きません。IEでも対応したい場合はこちらを参照くださいませ。
先日からBootstrapをいじっております。
サムネイル(thumbnail)を試しているのですが、2段目から左端がずれてしまうのです。
<ul class="thumbnails"> <% @images.each do |image| %> <li class="span3"> <a href="<%= image_path(image) %>" class="thumbnail"> <h3>サムネイル</h3> </a> </li> <% end %> </ul>
結果がこんな感じ。
調べてみると、みなさま色々な方法で回避されています。
margin-leftの値が、一番最初だけしか0になっていないことが問題なようです。
一番簡単そうなこの方法で行くことにしました。
cssに以下を追加。
ul.thumbnails li.span3:nth-child(4n + 1) { margin-left : 0px; }
この例では1つのボックスの幅を"span3"にしているので(上記html参照)、cssでもspan3を指定しています。
"4n+1"の部分ですが、一段に入るボックスの数に合わせてnの前の数字を変えて下さい。
例えばボックスの幅を"span2"にする場合、一段に6個のボックスが入るので、下記のようになります。
ul.thumbnails li.span2:nth-child(6n + 1) { margin-left : 0px; }
うまくいきました。
線を引く側と、引かれる側、どちらに属するかを決めるのは自分ではない
炎上芸で名を轟かせているイケダハヤト氏。
今回も日本人全員をターゲットにした挑発的なタイトルですが、内容に非常に共感しましたので、ご報告致します。
「生活保護の受給を厳格化せよ」と雄弁に語る人々は、自分たちがこの制度を利用する可能性があるという絶対的な事実を、信じられない鈍感さで見逃しているのでしょう。
自分で自分の首を絞めていることに気づかない日本人たち - ihayato.書店 | ihayato.書店
イケダハヤト、いいこと言った!
昨今の○○叩き、disりを見るたびに思うのは、まさにこれ、これに尽きる。
どうしてそこまで正義の御旗の元に発言できるのだろうと、不思議でしょうがないのです。
想像力の悲しいまでの欠如としか言い様がない。
自己責任という言葉を耳にする度、本当にそう思います。
自分が同じ境遇になる可能性を完全に排除した物言いは、イケダハヤト氏の言う通り社会をギスギスさせるだけで、最終的には発言者自身の首を締めることになるわけですが、絶対善・絶対正義の立場であることを信じて疑わない発言者は、そこがわからない。
というか、自分は間違わないので、そこに到達しようがない。
仮に、自分は間違っていないし、将来も間違わないとしましょう。
そう信じているのであれば仕方ないし、他人がどうこう言うことでもないですから。
でも、そうだとしても、忘れてはならない事があります。
自分が間違っているかどうかの線引をするのは、自分ではないという事です。
自分は線を引く側にいると思っていても、知らない間に線を引かれているということがある。
正義とか善悪って、そういうものだと思います。
だからこそ、線を引くときにはありたっけの想像力をもって、線を引かれる側にいる自分を思い浮かべなければならない。
ナチスがコミュニスト(共産主義者)を弾圧した時,私は不安に駆られたが,
マルティン・ニーメラーのことば
自分はコミュニストではなかったので,何の行動も起こさなかった。
その次,ナチスはソーシャリスト(社会主義者,労働組合員)を弾圧した。
私はさらに不安を感じたが,自分はソーシャリストではないので,何の抗議もしなかった。
それからナチスは学生,新聞人,ユダヤ人と,順次弾圧の輪を広げていき,
そのたびに私の不安は増大したが,それでも私は行動に出なかった。
ある日ついにナチスは教会を弾圧してきた。
そして私は牧師だった。
だから行動に立ち上がったが,その時は,すべてがあまりに遅過ぎた。
だいたいすぐに規制を作るけど、本来であれば、まずは運用で乗り切るべきでしょう。
いくら規制を厳しくしても、イケダハヤト氏が言うように本来利益を享受すべき人がそれを受けられなくなるだけで、インチキでも条件を揃えることのできるずるい人の方が有利になる。
生活保護なんて、現場を見ながら運用していくべき仕組みの最たるものだと思います。
twitter-bootstrap-rails のカスタマイズができない
twitter-bootstrap-railsのReadmeを読むと、bootstrap_and_overrides.css.lessで変数を上書きすれば色が変わるよと書いてあるのですが、何を書いても色が変わりません。
おまけに、navigation bar の class="brand" リンクにマウスオーバーすると、黒くなって非常にださい。
chromeのデバッガを使ってこの真っ黒の定義を調べると、scaffolds.cssで定義されているようだったので、app/assets/stylesheets/scaffolds.css.scssを削除したところ、マウスオーバーで黒くなるのが治りました。
もしやと思い、この状態でbootstrap_and_overrides.css.lessに "@linkColor: #ff0000" と追記したところ、ちゃんと色が変わったではないですか。
どこを見てもscaffold.css.scssをdisableしろなんて書いていないですし、カスタマイズできないYoなんて方もおられないようですので、私が何か変なことをしたのだと思います。
毎度、同じようにやっているのに動かないわけですが、同じじゃない何かをしているからこうなっちゃうんですよね、きっと。。。