ページのトップへスクロールするボタンを実装する

まずはデモ

http://workshops.ddns.net/albums/show_pictures/70#

以下に、コピペでそのまま使えるコードを貼ります

<style type="text/css">
   #topbutton {
      /* ▼表示位置を画面の右下に固定 */
      position: fixed; /* ←表示場所を固定 */
      bottom: 18px;   /* ←下端からの距離 */
      right: 18px;    /* ←右端からの距離 */
      width: 7em;     /* ←横幅 */

      /* ▼最初は非表示にしておく */
      display: none;

      /* ▼配色・配置・文字の装飾など */
      background-color: #2525aa; /* ←背景色 */
      opacity: 0.75;             /* ←透明度 */
      border-radius: 24px;       /* ←角丸の半径 */
      text-align: center;    /* ←文字の位置 */
      font-size: 120%;       /* ←文字サイズ */
      font-weight: bold;     /* ←文字の太さ */
      margin: 0px;    /* ←外側の余白 */
      padding: 10px;  /* ←内側の余白 */
   }
   #topbutton a {
      /* ▼リンクの装飾 */
      color: white;          /* ←文字色 */
      text-decoration: none; /* ←下線なし */
   }
   #topbutton a:hover {
      /* ▼マウスが載ったときの装飾 */
      color: yellow;              /* ←文字色 */
      text-decoration: underline; /* ←下線あり */
   }
</style>

<p id="topbutton">
   <a href="#top" onclick="$('html,body').animate({ scrollTop: 0 }); return false;">▲TOPへ戻る</a>
</p>

<script>
$(function() {
   // スクロールしたときに実行
   $(window).scroll(function () {
      // 目的のスクロール量を設定(px)
      var TargetPos = 350;
      // 現在のスクロール位置を取得
      var ScrollPos = $(window).scrollTop();
      // 現在位置が目的のスクロール量に達しているかどうかを判断
      if( ScrollPos >= TargetPos) {
         // 達していれば表示
         $("#topbutton").fadeIn();
      }
      else {
         // 達していなければ非表示
         $("#topbutton").fadeOut();
      }
   });
});
</script>

以上

【Ruby On Rails】コントローラーのメソッドに直接APIを発行した際の引数の渡し方

以下コントローラーのメソッド

class Api::V1::AlbumsController < ApplicationController
  respond_to :json

  def get_params(selectedTags=["旅行", "観光"])
    if params[:tags].present?
      selectedTags = params[:tags]
    end
  end

end

デフォルトでselectedTags配列には["旅行", "観光"]が入るようにしている。 リクエスト時にtagを指定した場合は、その指定した値が入るようになっている。

以下、タグを指定した場合のリクエストURL

http://example.com/api/v1/albums/get_params?tags[]='テスト'&tags[]='test'

レスポンス例

BODY
[
  "'テスト'",
  "'test'"
]

タグを指定しない場合

http://example.com/api/v1/albums/get_params

レスポンス例

BODY
[
  "旅行",
  "観光"
]

ちなみに、routes.rbには以下のように記述しておく

get "api/v1/albums/get_params"

参考

Action Controller の概要 | Rails ガイド

ruby on railsで関連レコードを集計する

目的

例えば、以下の場合

models/Album.rb

has_many: pictures

models/Picture.rb

belogns_to: albums

Album.pictures_countでAlbumの持つPictureを取得できるようにする。

Gem

gem 'counter_culture'

モデルの構造

アルバムが複数の写真を持つイメージ

# vi app/models/album.rb

class Album < ActiveRecord::Base
  has_many :pictures, :dependent => :destroy
end

# vi app/models/picture.rb

class Picture < ActiveRecord::Base
  belongs_to :album
  counter_culture :album
end

カラムの追加

# rails g counter_culture Album pictures_count
# rake db:migrate RAILS_ENV=production

既存の状態を反映

# rails c -e production  # 例ではproduction環境
# irb(main):001:0> Picture.counter_culture_fix_counts

確認

# irb(main):002:0> Album.first.pictures_count
=> 4

ここで、Album.first.pictures.countで出力される結果と同じならOK

また、中間テーブルがある場合は、中間テーブルのモデルに以下のように記述する。

class RoutePicture < ActiveRecord::Base
  belongs_to :route
  belongs_to :picture

  counter_culture :route, column_name: "pictures_count"
end

参考

関連レコード数の集計(カウンターキャッシュ) - Qiita

http://wonderwall.hatenablog.com/entry/2015/08/16/225116

gitのエラー error: RPC failed; result=18, HTTP code = 200 の対応

Gitの整理をしてたら、Git Cloneできないものがあった。 エラーはこんなの

error: RPC failed; result=18, HTTP code = 200| 29.99 MiB/s      
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

gitでPOST通信のバッファ制限に捕まったみたい。 容量が大きすぎることが原因。

バッファーを増やすことで回避できる

# git config --global http.postBuffer 524288000

python エンコード指定でファイルに出力

pythonで日本語を扱っていると以下のようなエラーに遭遇することが多い

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-8: ordinal not in range(128)

コーデックを指定することで、回避できる

ファイルに主力する場合は以下のようにする

import codecs

file = codecs.open('filename', 'ab', 'utf-8')
file.write(a + '\n')
file.close()

Google Mapでヒートマップを作成

Google Mapでヒートマップを作成する

Google Map APIを使うと、簡単にヒートマップを作成できます。

まずはサンプル

http://workshops.ddns.net/map/heat_map

さくっとサンプルコードを載せます

<div id="map_canvas"></div>
<script>

data =  [
{"Weight":31500,pos:[138.549837,36.534579]},
{"Weight":19600,pos:[138.552933,36.537296]},
{"Weight":4950,pos:[138.564714,36.461183]},
];


var data = gon.heat_map_data;

function initialize() {
    //地図初期化
    var initPos = new google.maps.LatLng(39.703531,141.152667); //地図の初期位置
    var myOptions = {
      noClear : true,
      center : initPos,
      zoom : 10,
      mapTypeId : google.maps.MapTypeId.ROADMAP
    };
    var map_canvas = new google.maps.Map(document.getElementById("map_canvas"), myOptions);    



    //ヒートマップ用のデータの作成
    var bounds = new google.maps.LatLngBounds();
    var  pos, populations = [];
    for (var i=0; i < data.length; i++) {
    pos = new google.maps.LatLng(data[i].pos[0], data[i].pos[1]);
    populations.push({
        location : pos,
        weight : data[i].picture_num //ヒートマップの重み付けに使用するデータを指定(写真数)
    })
    bounds.extend(pos); 
    }
    map_canvas.fitBounds(bounds); //全てのデータが画面に収まる様に表示を変更

    //ヒートマップレイヤの作成
    var heatmap = new google.maps.visualization.HeatmapLayer({
        radius:25 //ヒートマップの各ポイントの大きさ
    });

    heatmap.setData(populations);
    heatmap.setMap(map_canvas);


}
google.maps.event.addDomListener(window, "load", initialize);
</script>

Googleは、Weightをサーバーサイドで計算することを想定しているようです。

参考

Layers  |  Google Maps Javascript API  |  Google Developers

railsでアルバム管理機能を実装

前回の記事 railsで写真アップロード機能を実装 - watariseinの日記の続き。

投稿した写真群とアルバムを多対一で管理できるようにします。

1. 参照先の外部キーを追加する

まず、多側のテーブル(前回作成したpicturesテーブル)にxxx_idという名で外部キーを追加します。 xxxの箇所は参照先のモデル名にする必要があります。 今回の場合は、Albumモデルを参照するため、album_idにする必要があります。

Albumモデルとalbumsテーブルの作成をします。

$ rails g model Album name:string
$ rake db:migrate

album_idを外部キーとしてpictureテーブルに追加するマイグレーションファイルを作成します。

$ rails g migration add_album_id_to_pictures album_id:integer
$ rake db:migrate

ちなみに、新規にPictureモデルを作成する場合は以下の手順で作成します。

$ rails g model Pcture album_id:integer date:date
$ rake db:migrate

2. モデルファイルに1対多関連の宣言を追加

モデルにhas_manyとbelongs_toを追加する

「1側」のAlbumにhas_manyを追加します。 "Album has_many pictures"と読めば、「Albumは複数のPictureを持つ」となります。 また、dependent: :destroyオプションを追加することで、albumレコードをdestoryメソッドで削除したら、Railsがそのalbumに紐づいていたpictureを全て削除してくれます。

「多」側の編集

$ vi app/models/album.rb
class Album < ActiveRecord::Base
  has_many :pictures, dependent: :destroy
end

has_manyメソッドには次のようなオプションを指定できます。

class_nameオプションで関連するモデルのクラス名を指定でき、関連名と参照先のクラス名を異なるものにできる。 foreign_keyオプションで参照先を参照する外部キーの名前を指定できる。デフォルトは、参照先のモデル名_id dependentオプションで親オブジェクトが削除された時の扱いを指定できる。destroyとdelete_allなどが指定可能。 asオプションでポリモフィック関連を定義できる。 throughオプションでモデル接続の関連を設定できる。 など

「多側」にbelongs_toメソッドを記載します。 "Picture belogns_to album"と読めば、「Pictureは1つのAlbumに属する」となります。

$ app/models/picture.rb
class Picture < ActiveRecord::Base
  belongs_to :album
end

belogns_toメソッドには次のようなオプションを指定できます。

class_nameオプションで関連するモデルのクラス名を指定でき、関連名と参照先のクラス名を異なるものにできできる。 foreign_keyオプションで参照先を参照する外部キーの名前を指定できる。デフォルトは、参照先のモデル名_id dependentオプションで親オブジェクトが削除された時の扱いを指定できる。destroyとdeleteが指定可能。 polymorphicオプションでポリモフィック関連を定義できる。 など

例えば、デフォルトのpicture.albumではなく、picture.photo_bookでアクセス可能にする

# app/models/order.rb 多側
class Picture < ActiveRecord::Base
  belongs_to :photo_book, class_name: "Album", foreign_key: "album_id"
end

4. 使えるようになるメソッド

これらを追加することで自動的に次のようなメソッドが使えるようになります。

# 作成
album = Album.create(name: "あるばむ1") # albumを作成し、DBに保存
picture1 = album.pictures.build(date: Time.now) # picture1を作成(newの代わりにbuildを使う)
picture1.save # picture1をDBに保存
picture2 = album.pictures.create(date: Time.now) # picture2を作成し、保存

# リレーション
album.pictures         # => pictureオブジェクトの配列
album.pictures.exists? # => true (存在するか判定する)
album.pictures.empty?  # => false (空か判定する)
picture1.album     # => albumオブジェクト(pictureを所持しているalbum)

# album.pictures内のレコードのみから検索ができる
album.pictures.find(...)
album.pictures.find_by(...)
album.pictures.where(...)

# 削除
album.count # => 2
album.destory # => dependent: :destroyが指定されているので、pictureも削除される
album.count # => 0

これで、アルバムと写真の多対一構成の構築が完了した。 次回は写真を複数登録できるようビューなども作成する