ActiveRecord öznitelik yöntemlerini geçersiz kılma


150

Neden bahsettiğime bir örnek:

class Person < ActiveRecord::Base
  def name=(name)
    super(name.capitalize)
  end
  def name
    super().downcase  # not sure why you'd do this; this is just an example
  end
end

Bu işe yarıyor gibi görünüyor, ama sadece öznitelik yöntemleri geçersiz kılma bölümü okudum ActiveRecord :: Base belgelerinde ve read_attributeve write_attributeyöntemlerini kullanmanızı önerir . Yukarıdaki örnekte yaptığım şeyde yanlış bir şey olması gerektiğini düşündüm; aksi halde, bu yöntemleri neden öznitelik yöntemlerini geçersiz kılmanın "doğru yolu" olarak kutsarlar? Ayrıca daha çirkin bir deyim de zorluyorlar, bu yüzden iyi bir neden olmalı ...

Asıl sorum: Bu örnekte bir sorun mu var?

Yanıtlar:


211

Gareth'in yorumları yankılanıyor ... kodunuz yazıldığı gibi çalışmaz. Bu şekilde yeniden yazılmalıdır:

def name=(name)
  write_attribute(:name, name.capitalize)
end

def name
  read_attribute(:name).downcase  # No test for nil?
end

Tam olarak ihtiyacım olan şey. Teşekkürler Aaron.
bong

18
Bu artık doğru değil. Ya süper ya da şimdi çalışıyor. Ancak karma gösterimi test etmedim.
heartpunk

2
Ray 3'te, burada Aaron tarafından belirtilen okuyucu yöntemi çalışır, ancak belirtilen orijinal posterin (adı süperya besleyen) yazar iyi çalışır ve IMHO, özniteliği Aaron'un önerdiği gibi manuel olarak yazmaktan daha temizdir.
Batkins

1
Aşağıda mipadi tarafından verilen karma yöntemi test ettim ve bir çekicilik gibi çalışıyor (Rails v 3.2.6)
almathie

Doğru cevap değil mi? Teşekkürler @Aaron, benim için de çalıştı.
Sadiksha Gautam

94

Aaron Longwell'in cevabının bir uzantısı olarak, geçersiz kılınmış erişimcilere ve mutasyona sahip özelliklere erişmek için bir "karma gösterim" kullanabilirsiniz:

def name=(name)
  self[:name] = name.capitalize
end

def name
  self[:name].downcase
end

Hash gösterimi işe yarayabilir, ancak self.attributeyığını 3.2.16'ya üfler.
jrhorn424

Bu, ||=varsayılan olarak destekleme avantajına sahiptir :def name; self[:name] ||= 'anon'; end
Paul Cantrell

Benim için bu karma gösterim işe yarıyor. Ama neden işe yaradığını bilmiyorum. Birisi açıklayabilir mi?
radiantshaw


-1

Ben beklediğiniz gibi özellik geçersiz kılma öznitelik geçersiz kılan yapar bir raylar eklentisi var. Github'da bulabilirsiniz .

Yüklemek:

./script/plugin install git://github.com/chriseppstein/has_overrides.git

Kullanmak:

class Post < ActiveRecord::Base

  has_overrides

  module Overrides
    # put your getter and setter overrides in this module.
    def title=(t)
      super(t.titleize)
    end
  end
end

Bunu yaptıktan sonra işler işe yarar:

$ ./script/console 
Loading development environment (Rails 2.3.2)
>> post = Post.new(:title => "a simple title")
=> #<Post id: nil, title: "A Simple Title", body: nil, created_at: nil, updated_at: nil>
>> post.title = "another simple title"
=> "another simple title"
>> post.title
=> "Another Simple Title"
>> post.update_attributes(:title => "updated title")
=> true
>> post.title
=> "Updated Title"
>> post.update_attribute(:title, "singly updated title")
=> true
>> post.title
=> "Singly Updated Title"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.