sequelizeでidに0が入ってしまう
sequelizeでidに0が入ってしまう
環境
- MariaDB 10.1.9 (Homebrew)
概要
SequelizeでdialectとしてMySQLをした際に、 AUTO_INCREMENTカラムを含むテーブルに対してINSERTすると0が入ってしまう可能性がある。
Sequelize
SequelizeはNode.js用のORMである。
まず、下記のようなテーブルがあるとする
CREATE TABLE `Users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ここで、sequelizeで定義したModelからnameカラムのみを指定してinsertすると 下記のようなSQLが発行される
INSERT INTO `Users` (`id`,`name`) VALUES (DEFAULT,'sequelize');
この時、設定によってはUsersに追加されるレコードは下記のようなものになる場合がある
select * from Users; +----+-----------+ | id | name | +----+-----------+ | 0 | sequelize | +----+-----------+
NO_AUTO_VALUE_ON_ZERO
https://dev.mysql.com/doc/refman/5.6/ja/faqs-sql-modes.html
sql_modeの1つにNO_AUTO_VALUE_ON_ZEROがあり、 これを設定すると、INSERT時にAUTO_INCREMENTカラムに対して0を指定しても自動採番されなくなります。
NO_AUTO_VALUE_ON_ZERO は AUTO_INCREMENT カラムの処理に影響します。通常は、NULL または 0 をカラムに挿入することによって、カラムの次のシーケンス番号を生成します。NO_AUTO_VALUE_ON_ZERO は 0 のこの動作を抑制するため、NULL のみが次のシーケンス番号を生成します。
https://dev.mysql.com/doc/refman/5.6/ja/sql-mode.html
また、MySQLでは数値型の初期値は0なので、DEFAULTは0にります。 https://dev.mysql.com/doc/refman/5.6/ja/data-type-defaults.html
なので、NO_AUTO_VALUE_ON_ZEROを設定している状態でidに対してDEFAULTを指定すると 必ずidに0が入るようになってしまいます。
対応
下記SQLでsql_modeを確認、設定することができます。 状況に応じて、適切なsql_modeを設定すれば良さそう?
SELECT @@GLOBAL.sql_mode; SELECT @@SESSION.sql_mode; SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'; SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
まとめ
Sequelizeを使うときは、sql_modeの設定を事前に確認しましょう。 MySQLに対しての知識が全然ないので、地味にハマりました。。。
RMagickでフォントが使用できない、unable to read font `(null)'
環境
- Mac OS X 10.10.2
- Ruby 2.2.0
- ImageMagick 6.9.0
- RMagick 2.13.4
unable to read font `(null)'
rmagick
でテキストを表示しようと思ったら何故かunable to read font
(null)'`とかいうエラーが。。。
rmagick
で使用できるフォントを見てみると、使用可能なフォントが1つもない。。。
require 'RMagick' Magick.fonts => []
設定ファイルを確認
設定ファイルを確認してみると、--with-gs-font-dir=/usr/local/share/ghostscript/fonts
という部分がある。
どうやら、ここにあるフォントを読み取って使用しているらしいが、そんなディレクトリは存在しない。。。
$ cat /usr/local/lib/ImageMagick/config-Q16/configure.xml
ghostscript
無いのであればinstallしてみる
$ brew install ghostscript
無事フォントが読み込まれました
require 'RMagick' Magick.fonts => [#<struct Magick::Font name="AvantGarde-Book", ...]
.btn-groupにtooltipを使うとデザインがズレる
環境
- Mac OS X 10.10.2
- Google Chrome 41.0.2272.101 (64-bit)
- Bootstrap 3.3.4
.btn-groupにtooltipを使うとデザインがズレる
.btn-group
内のbutton
にtooltip
を使用すると、
tooltip
が発動した時に1px程度ズレが生じてしまいます。
<div class="btn-group" role="group"> <button type="button" class="btn btn-default" data-toggle="tooltip" title="Tooltip"> Left </button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div>
何故ズレが生じているのか?
Bootstrapのソースコードを見てみると、隣接している.btn
にmargin-left: -1px;
が指定されているようです。
.btn-group { .btn + .btn, .btn + .btn-group, .btn-group + .btn, .btn-group + .btn-group { margin-left: -1px; } }
しかし、tooltip
を使用するとtooltip
の対象となっている.btn
の後にDOMが追加されてしまい、.btn
同士が隣接している状態ではなくなってしまいます。
そうすると、上記cssが適応されないのでレイアウトがズレてしまっているようです。
ズレが生じないようにする
対処法としてはdata-container
をbody
等に設定してあげればOKです。
<div class="btn-group" role="group"> <button type="button" class="btn btn-default" data-toggle="tooltip" data-container="body" title="Tooltip"> Left </button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div>
参考
Bootstrapの公式サイトにもdata-container
を指定するよう載っていますね。
When using tooltips on elements within a .btn-group or an .input-group, you'll have to specify the option container: 'body' (documented below) to avoid unwanted side effects (such as the element growing wider and/or losing its rounded corners when the tooltip is triggered).
Drawableに設置したpngファイルのオリジナルサイズを取得する
AndroidにてDrawableに設置したpngファイルのサイズを取得しようとしたら、ちょっとはまったのでメモ。
前提
drawableに 50 * 50 px の画像ファイルを設置。
res/drawable/sample.png
画像サイズを取得
リソースIDからBitmap
を生成して#getWidth, #getHeight
でサイズを取得したら、
実際のサイズとは異なる値が取得される。。。
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.sample); int w = b.getWidth(); int h = b.getHeight(); // w => 150; h => 150;
そんな時はBitmapFactory.Options
から値を取得してあげれば、
オリジナルの画像サイズが取得出来ました( ´ー`)フゥー...
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.drawable.sample, options); int w = options.outWidth; int h = options.outHeight; // w => 50; h => 50;
参考
http://stackoverflow.com/questions/8855036/incorrect-image-dimensions-in-android-when-using-bitmap
Enumerable#map and Array#flatten vs Enumerable#flat_map
目的
- Enumerable#map, Array#flatten と Enumerable#flat_map でどちらがパフォーマンスに優れているかを調べる。
環境
Enumerable#flat_map
flat_map (Enumerable) - APIdock : http://apidock.com/ruby/Enumerable/flat_map
ベンチマーク
require 'benchmark' n = 1000 array = Array.new(100) { |i| Array.new(i) { |j| j } } Benchmark::CAPTION Benchmark.bm do |x| x.report('flat_map') { n.times { array.flat_map { |a| a } } } x.report('flat map') { n.times { array.map { |a| a }.flatten(1) } } end
user system total real flat_map 0.030000 0.010000 0.040000 ( 0.036725) flat map 0.260000 0.020000 0.280000 ( 0.271837)
まとめ
map
, flatten
ではなくflat_map
を使ったほうが速くなっていますね。
ただ、flat_map
では1段階までしか平坦化されないで使用する際には注意が必要かもしれないです。
irb(main):055:0> [[1, 2], [[3, 4, 5]]].flat_map { |x| x } => [1, 2, [3, 4, 5]]
Railsで独自クラスにバリデーションを実装してみる
環境
独自クラスにValidationを実装
独自クラスでRailsのValidationを実装したい場合はActiveModel::Validations
をincludeしてあげればよいらしい。
class Hoge include ActiveModel::Validations validates :hoge_id, presence: true def initialize(attributes = {}) attributes.each do |name, value| send("#{name}=", value) end end end
これで、大丈夫かと思ったがNoMethodError
が出てしまった。
[1] pry(main)> Hoge.new(hoge_id: 100) NoMethodError: undefined method `hoge_id=' for #<Hoge:0x007fc71ce47bf0> from /path/to/hoge.rb:8:in `block in initialize'
なので、attr_accessor :hoge_id
を指定してあげればエラーは消えた.
class Hoge include ActiveModel::Validations attr_accessor :hoge_id # 追加 validates :hoge_id, presence: true def initialize(attributes = {}) attributes.each do |name, value| send("#{name}=", value) end end end
これで、ひとまず独自クラスでもバリデーションを行うことが出来るようになりました。
[5] pry(main)> hoge = Hoge.new(hoge_id: nil) [6] pry(main)> hoge.valid? => false [7] pry(main)> hoge.errors.full_messages => ["Hogeを入力してください。"]
参考
CoffeeScriptのファットアローって何だ?
ファットアロー
jQueryのコールバック関数で呼ばれた関数でthis
を使うと関数内のjQueryオブジェクトを指しているため、
that = @
等と関数外で別の変数に置き換えて使用することがあると思います。
coffee
class User constructor: (first_name, last_name) -> @full_name = "#{first_name} #{last_name}" that = @ $("#action-hello").click -> alert "My name is #{that.full_name}."
js
var User; User = (function() { function User(first_name, last_name) { var that; this.full_name = "" + first_name + " " + last_name; that = this; $("#action-hello").click(function() { return alert("My name is " + that.full_name + "."); }); } return User; })();
そんな時、アロー->
ではなくファットアロー=>
を使ってあげると
@
に対してスコープ外のthis
へと自動的に置き換えを行ってくれます。
coffee
class User constructor: (first_name, last_name) -> @full_name = "#{first_name} #{last_name}" $("#action-hello").click => alert "My name is #{@full_name}."
js
var User; User = (function() { function User(first_name, last_name) { this.full_name = "" + first_name + " " + last_name; $("#action-hello").click((function(_this) { return function() { return alert("My name is " + _this.full_name + "."); }; })(this)); } return User; })();
感想
ファットアローなんてものがあったんですね、知らなかった自分が情けないです。。。