初めのアルファベットに該当するレコードのみ表示するメソッドの定義の仕方
models
def self.by_letter(letter) where("lastname LIKE ?", "#{letter}%").order(:lastname) end
controller
def index if params[:letter] @contacts = Contact.by_letter(params[:letter]) else @contacts = Contact.order('lastname, firstname') end end
view
<% ('A'..'Z').each do |letter| %> <%= link_to letter, contacts_path(letter: letter) %> <% end %> <%= link_to 'All', contacts_path %>
bootstrapも適用すれば、こんな感じのviewを出力してくれる。
姓と名でわけて入力するが、出力は毎回姓と名を連結するときのメソッドの作成方法
app/models/hoge.rb
def name [firstname, lastname].join(' ') end #もしくは def name firstname + lastname end
RailsでAさんは同じ連絡先を登録できないが、AさんとBさんで同じ連絡先を登録できるバリデーションの設定方法
app/models/contact.rb
class Contact < ActiveRecord::Base has_many phones
phoneモデルで同じcontact_idは持てないようにuniqunessな制約をつけると実現できる。
app/models/phone.rb
class Phone < ActiveRecord::Base belongs_to :contact validates :phone, uniquness: { scope: :contact_id }
Railsで掲載期間の有無を設定する実装方法
チェックボックスにチェックを入れた時はずっと掲載し続ける場合の実装方法
check_boxは引数をつけなかった場合、チェックした場合は1を、つけない場合は0が値として渡される。
form.html.erb
<%= form.check_box :no_expiration %>
アクセスメソッドを定義する。 それなら、attr_accessor使えばいいじゃんと思うけど、今回はただ、値を読みだしたり、書き出したりするのでは、事足りないので独自に定義する必要がある。 check_boxにチェックがつけられていた場合、つまり1が渡された場合に、@no_expirationをtrueにして、そうでなければfalseにする。 メソッドの中身を普段なら@no_expiration = valだけにするが、valの値をそのまま代入するのではなく、今回はtrueかfalseを代入したいので、独自に定義している。 model.rb
def no_expiration=(val) @no_expiration = val.in?([true, 1, "1"]) end
expired_atの有無によって、falseかtrueを返す。 model.rb
def no_expiration expired_at.blank? end
Rubyのputsメソッド、printメソッドはto_sメソッドを定義すると
改訂3版基礎 Ruby on Rails (KS IMPRESS KISO SERIES)でどうしてもわからないことがあった。
untitled.rb class Robot def initialize(name) @name = name @x = @y = 0 end def move(x,y) @x += x; @y += y end def to_s "#{@name}: #{@x},#{@y}" end end robo1 = Robot.new("ロボ1号") robo2 = Robot.new("ロボ2号") puts robo1 robo2.move(10,20) puts robo2
このコードを実行すると
$ ruby untitled.rb ロボ1号: 0,0 ロボ2号: 10,20
と出力される。to_s
メソッド呼び出してないけど、なんでto_s
メソッド呼び出されているのかがわからなかった。
試しにp
で出力させてみると表示が変わった。
#<Robot:0x007fdaaa0aa0f0 @name="ロボ1号", @y=0, @x=0> #<Robot:0x007fdaaa0aa0a0 @name="ロボ2号", @y=20, @x=10>
もう少しググってみると答えがわかった。
putsメソッドとprintメソッドはレシーバをto_s
メソッドで文字列に変換してから出力する。
つまり、自分でto_sメソッドを定義すると、to_s
メソッドの機能を上書きできてしまうようだ。
これを調べるのに1時間くらい時間がかかった。