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.