saveとsave!
saveは失敗時にfalseを返す。
@hoge = Hoge.new(:name => "piyo") if @hoge.save p "ゆっくりしていってね!" else p "ぬるぽ" end
save!は失敗時に例外を返す。
@hoge = Hoge.new(:name => "piyo") begin @hoge.save! p "ゆっくりしていってね!" rescue p "ぬるぽ" end
トランザクション内(ロールバック可能)の時は、ふつうはsave!。
@hoge = Hoge.new(:name => "piyo") begin Hoge.transaction do @hoge.save! end p "ゆっくりしていってね!" rescue p "ぬるぽ" end
ちなみにtransactionを生やしてるクラスはHogeってより、親クラスなので、以下な感じでいいかも。
@hoge = Hoge.new(:name => "piyo") begin ActiveRecord::Base.transaction do @hoge.save! end rescue => ex logger.error("【例外発生】:" + ex.message + "\n" + ex.backtrace.join("\n")) end
form関連
- 特定のモデルに結びついたform_for, text_field、そうではない時のform_tag, text_filed_tag。
- text_fieldの場合、パラメータやキーもハッシュ化される(params[:aaa][:bbb])。
<%= form_for(@foo) do |f| %> <%= f.text_field :name %> <%= f.submit %> <% end %>
# create アクション @foo = Foo.new(params[:foo]) # update アクション @foo = Foo.find(params[:id]) @foo.update_attributes(params[:foo])
クラスとか
- @はじまりがインスタンス変数、@@はじまりがクラス変数、$はじまりがグローバル変数(宣言は不要)。
- アルファベット大文字 ([A-Z]) で始まる識別子は定数。
class Sequence include Enumerable # Enumerable モジュールのメソッドを読み込む。 # 自動的に呼び出される初期化メソッド。 def initialize(from, to, by) @from, @to, @by = from, to, by # @始まりのインスタンス変数に多重代入。 end def length return 0 if @from > @to Integer( (@to - @from) / @by ) + 1 end # 別名登録 alias size length end
class Point attr_accessor :x, :y # セッタとゲッタを設定。(以前はattrだけだった) # attr_reader :x, :y # イミュータブル(値を変更しない)ならこちら。 @@n = 0 # 作成したPointの数 def initialize(x, y) @x, @y = x, y end def self.report p "作成されたPointの数=#@@n" end end p = Point.new(0, 0)
selfが付くとクラスメソッド、付かないとインスタンスメソッド
インスタンスメソッドは、インスタンスを生成してそこからでないと呼べない。
クラスメソッドなら、(インスタンスを作成せずに)そのまま呼べる。
class Benri def plus_one end def self.plus_two end
ちなみに、クラスメソッドの中でのselfはクラスを指し、インスタンスメソッド内ではそのインスタンスを指す。
privateと書いた行より後のメソッドはプライベート(上にパブリックメソッドがある)。
nil? empty? blank? present?
- nilは存在しない、emptyは入れ物はあるけど空っぽ、nilとemptyを合わせたのがblank、blankの反対がpresent。
Rails
ActiveSupport
Railsのもっとも汎用的なライブラリ。
require 'active_support'
nil?とempty?はrubyのメソッドで、blank?とpresent?はrailsで拡張されたメソッド。
blank?は、nilも空も半角スペース/タブ/改行もtrue。
" ".blank? => true
# 複数形化 "card".pluralize => "cards" # 単数形化 "cards".singularize => "card" "ActiveRecord::Base".undersocre => "active_record/base" "active_record/base".camelize => "ActiveRecord::Base" "ActiveRecord::Base".constantize => ActiveRecord::Base # 変数から定数 SAKAI = 'yugo' p 'SAKAI'.constantize => "yugo" # モデル.new 'sakai_report'.camelize.constantize.new
Time.days_in_month(2, 2000) => 29 Time.days_in_month(2, 2011) => 28
['a', 'b', 'c'].to_json => ["a", "b", "c"] {:name => 'Tama', :type => 'Cat'}.to_json => {"name":"Tama","type":"Cat"}
121.multiple_of?(11) => true 122.multiple_of?(11) => false
ActiveRecord
クラス=テーブル、属性=カラム。
クラス=ActiveRecord::Baseの派生クラス。app/models配下に配置。
Railsは複合主キーには対応していません。開発を簡単にするために、複合主キーは避けるのがよいでしょう。レガシーデータベースを使うといった制約がある場合は、一意になるプライマリキーを新しく追加するなどして回避するのがおすすめです。
class User < ActiveRecord::Base set_table_name :kaiin set_primary_key :member_code end
# INSERT user = User.new(:name => ‘Taro’, :email => ‘taro@everyleaf.com’) user.save # 違う書き方 user = User.new user.name = 'Taro' user.email = 'taro@everyleaf.com' # 更新 user = User.find(requested_id) user.name = ‘Jiro’ user.save # 削除 user = User.find(requested_id) user.destroy
# 特定IDのレコード参照 user = User.find(requested_id) User.find(1) User.last User.find(1, 2) # 1000件(初期値)ずつ取得して1件ずつループ。 User.find_each do |user| … end # 5000件ずつに変更。 User.find_each(:batch_size => 5000) do |user| … end # 検索 User.all(:conditions => [‘age = ?’, 31]) User.all(:conditions => [‘age = ?’, 31], :order => ‘created_at desc’, :limit => 20) User.where(:age => 31) User.where(:age => [31, 32]) User.where(:age => 30..40) # 範囲 # プレースホルダ User.where('age = ? AND name = ?', 31, 'jugyo')
Ruby and Perl
Ruby | Perl |
---|---|
#!ruby 'hello' %q{hello} %q!hello! "hello\n" %Q{hello\n} %Q!hello\n! %w{a bb ccc d} %x{ls} |
#!perl 'hello' q{hello} q!hello! "hello\n" qq{hello\n} qq!hello\n! qw{a bb ccc d} qx{ls} # = `ls` |
<<EOS あいうえお かきくけこ EOS |
<<EOS あいうえお かきくけこ EOS |
<<'EOS' あいうえお かきくけこ EOS |
<<'EOS' あいうえお かきくけこ EOS |
<<"EOS" あいうえお かきくけこ EOS |
<<"EOS" あいうえお かきくけこ EOS |
# 末尾の識別子(EOS)の行頭にインデントが可能。 <<-"EOS" あいうえお かきくけこ EOS |
# |
<<"EOS" print(Kconv.tosjis(<<"EOS")) あいうえお かきくけこ EOS |
# |
name = '鈴木' + '一郎' |
my $name = '鈴木' . '一郎'; |
name = '鈴木'; print("私は#{name}です。") print("私は#{30 + 6}才です。") |
my $name = '鈴木'; print "私は@{[ $name ]}です。"; print "私は@{[ 30 + 6 ]}才です。"; |
'あ' * 10 |
'あ' x 10 |
name = '鈴木' name << '一郎' # 以下も同じ。 name.concat('一郎') |
my $name = '鈴木'; $name .= '一郎'; |
10進数 214 2進数 0b11010110 8進数 0326 16進数 0xD6 |
10進数 214 2進数 0b11010110 8進数 0326 16進数 0xD6 |
3_420_500 |
3_420_500 |
# 四則演算等 + - * / % ** |
# 四則演算等 + - * / % ** |
# 引数をそのまま出力。 print "abc\n" # 末尾に改行をつけて出力。 puts 'abc' # 引数が文字列の時ダブルクオートで囲って出力。 p 'abc' |
# |
# コメント =begin 複数行 =end |
# コメント =for comment 複数行 =cut |
# 変数の1文字目数字NG # 変数に使えない予約語の例 BEGIN class ensure nil self when END def false not super while alias defined? for or then yield and do if redo true begin else in rescue undef break elsif module retry unless case end next return until |
# |
num += 2 num -= 2 num *= 2 num /= 2 num %= 2 num **= 2 num += 1 num -= 1 |
$num += 2; $num -= 2; $num *= 2; $num /= 2; $num %= 2; $num **= 2; $num ++; $num --; |
# falseとnilは偽 # falseとnil以外は全て真 |
# |
# 関係演算子 == != > >= < <= # 論理演算子 && || ! |
# 関係演算子 == != > >= < <= # 論理演算子 && || ! |
# thenは省略可。 if num == 10 then p 'a' elsif num == 20 then p 'b' else p 'c' end unless num == 5 then p 'd' end flag = result > 10 ? 1 : 0 p 'e' if debug p 'e' unless debug |
if (num == 10) { print 'a'; } elsif (num == 20) { print 'b'; } else { print 'c'; } unless (num == 5) { print 'd'; } my $flag = $result > 10 ? 1 : 0; print 'e' if $debug; print 'e' unless $debug; |
array = [2005, 2006, 2007, 2008] p array[0] p array.at(0) array[0] = 1999 size = array.length |
my @array = (2005, 2006, 2007, 2008); print $array[0]; $array[0] = 1999; my $size = scalar @array; |
for value in array do p value end array.each{|value| p value } |
for my $value (@array) { print $value; } |
hash = {'name' => 'sakai', 'address' => 'Tokyo'} p hash['name'] p hash.fetch('name') hash['tel'] = '0123' hash.store('tel', '0123') |
my %hash = (name => 'sakai', address => 'Tokyo'); print $hash{name}; $hash{tel} = '0123'; |
hash.each{|key, value| p key + ' -> ' + value } hash.each_key{|key| p key + ' -> ' + hash[key] } |
while (my ($key, $value) = each %hash) { print $key . ' -> ' . $value; } for my $key (keys %hash) { print $key . ' -> ' . $hash{$key}; } |
def print_hello p 'hello' return 1 end def print_message(text) p text end def print_message(text = 'MESSAGE') p text end def print_message(*texts) texts.each{|text| p text } end |
sub print_hello { print 'hello'; return 1; } sub print_message { my $text = shift @_; print $text; } sub print_message { my $text = shift @_ || 'MESSAGE'; print $text; } sub print_message { my $texts = shift @_ || []; for my $text (@$texts) { print $text; } } |
value1, value2 = method(3, 7) |
my ($value1, $value2) = method(3, 7); |
# 整数→浮動小数点数 num.to_f # 浮動小数点数→整数(小数点以下切り捨て) f.to_i num.round # 四捨五入 num.ceil # 大きい方へ num.floor # 小さい方へ num.to_s # 文字列へ num.to_s(2) # 2進数へ num.to_s(8) # 8進数へ |
# |
class Person def initialize(person_name='カー') @name = person_name end attr_accessor :name end person = Person.new() person.name = 'sakai' p person.name # attr_accessorの他にattr_reader, attr_writerがあり。 |
my $person = Person->new; $person->name('sakai'); print $person->name; package Person; sub new { my $class = shift; my $name = shift; my $self = { name => $name }; return bless $self, $class; } sub name { my $self = shift; if (my $name = shift) { $self->{name} = $name; return $self; } return $self->{name}; } 1; |
# 継承とスーパメソッドの呼び出し class Baker < Person def work super p 'bake' end end |
package Baker; parent 'Person'; sub new { my $class = shift; bless {}, $class; } sub work { my $self = shift; $self->SUPER::work; print 'bake'; } |
text = 'hello'; chars = text[1, 2]; |
my $text = 'hello'; $chars = substr $text, 1, 2; |
array.length array.flatten array.uniq array.compact array.delete(val) array.delete_at(ind) array.delete_if {|x| x % 2 == 0 } array.reverse array.sort array.sort {|a, b| a <=> b } |
# |
t = Time.now p t.year p t.month p t.day p t.strftime("%Y-%m-%d %H:%M%S") |
# |
rbenv gem Bundler |
plenv cpanm Carton |
b = a.push(5) # あるいは b = a << 5 # 末尾に追加 b = a.pop # 末尾を削除 b = a.shift # 先頭を削除 b = a.unshift(5) # 先頭に追加 |
my @b = push @a, 5; # 末尾に追加 my $b = pop @a; # 末尾を削除 my $b = shift @a; # 先頭を削除 my @b = unshift @a, 5; # 先頭に追加 |
text = "aa-bb-cc" array = text.split("-") or array = text.split(/-/) array = text.split # 空白系文字で分割(先頭と末尾の空白系文字も消す) array = text.split("") text = array.join("/") text = array.join |
my $text = 'aa-bb-cc'; my @array = split /-/, $text; my @array = split /\s+/, $text; my @array = split //, $text; my $text = join '/', @array; my $text = join '', @array; |
# 構文チェック ruby -c test.rb |
# 構文チェック perl -c test.pl |
# |
# |
表記ルール抜粋
# 真偽値を返すメソッド名は、動詞または形容詞に`?'を付け、形容詞に `is_'は付けない。 visible? # 破壊的なメソッドと非破壊的なメソッドの両方を提供する場合、破壊的なメソッドには`!'を付ける。 split split! # splitの破壊的バージョン