nu pot accesa mutații ActiveRecord într-un bloc

Sunt în interiorul unui controler Rails și încerc să accesez variabila instanței într-un bloc: Aceasta dă o eroare spunând că "nici un câmp de metodă1 pentru Nil":

Prawn::Document.generate("hello.pdf") do
  @model.field1
end

Cu toate acestea, dacă fac acest lucru, atunci funcționează:

my_model = @model
Prawn::Document.generate("hello.pdf") do
  my_model.field1
end

Ar putea avea aceasta legătură cu accesoriile ActiveRecord sau cu variabilele de instanță într-un bloc?

0
Multumesc, cred ca acest thread are raspunsuri mai bune: P Nu cred ca ar fi logic sa imbinam aceste doua fire intr-unul singur.
adăugat autor m33lky, sursa
Această întrebare ar trebui să răspundă și dvs.: stackoverflow.com/questions/5150483/…
adăugat autor topek, sursa

2 răspunsuri

Acest tip de problemă apare când un bloc este executat într-un context diferit, de obicei printr-un instance_eval . Hai să verificăm codul:

#lib/prawn/document.rb: Document#initialize    
if block
  block.arity < 1 ? instance_eval(&block) : block[self]
end

Acolo aveți instance_eval și puteți vedea și soluția: trimiteți un bloc care acceptă documentul ca argument și acum veți putea accesa variabilele de instanță ca de obicei:

Prawn::Document.generate("hello.pdf") do |doc|
  @my_model.field1
end
3
adăugat

Acest lucru se întâmplă deoarece codul din interiorul blocului este executat în contextul obiectului Prawn :: Document. Hai să intrăm în acest cod:

module Prawn
  class Document
    def self.generate(filename,options={},&block)
      pdf = new(options,&block)
      pdf.render_file(filename)
    end

    def initialize(options={},&block)
      if block
        block.arity < 1 ? instance_eval(&block) : block[self]
      end
    end
  end
end

După cum puteți vedea, block este executat ca obiect Document ca self . Se încearcă să se găsească @model ca variabila de exemplu a self , nu se poate face acest lucru și se poate reveni zero . Dacă folosiți modelul variabil local, obțineți ajutor de închidere și codul dvs. funcționează corect

1
adăugat
De asemenea, există o metodă scurtă de a transforma o variabilă de instanță într-o variabilă în Ruby, fără a pierde o linie ca cea pe care am făcut-o cu my_model = @model ?
adăugat autor m33lky, sursa