kan ActiveRecord-mutators niet in een blok openen

Ik zit in een Rails-controller en probeer toegang te krijgen tot mijn instantievariabele in een blok: Dit geeft een foutmelding dat "no method field1 for Nil":

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

Als ik dit echter doe, werkt het:

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

Zou dit iets te maken kunnen hebben met ActiveRecord accessors of instantievariabelen in een blok?

0
Bedankt, ik denk dat deze thread echter betere antwoorden heeft: P Ik denk niet dat het zinvol zou zijn om deze twee threads samen te voegen.
toegevoegd de auteur m33lky, de bron
Deze vraag moet ook van u zijn: ruby block "> stackoverflow.com/questions/5150483/…
toegevoegd de auteur topek, de bron

2 antwoord

Dit soort problemen verschijnt wanneer een blok in een andere context wordt uitgevoerd, meestal via een exemplaar_eval . Dus laten we de code controleren:

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

Daar heb je je instance_eval en je kunt ook de oplossing zien: geef een blok door dat het document als argument accepteert en je hebt nu toegang tot de instantievariabelen zoals gewoonlijk:

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

Dat gebeurt omdat code in blok wordt uitgevoerd in de context van Prawn :: Document-object. Laten we naar deze code gaan:

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

Zoals u ziet, wordt block uitgevoerd met het object Document als self . Het probeert @model te vinden als instantievariabele van self , kan dit niet doen en nul retourneren. Als u de lokale variabele model gebruikt, krijgt u hulp van sluitingen en werkt uw code correct

1
toegevoegd
Is er ook een korte manier om een ​​instantievariabele om te zetten in een variabele in ruby zonder een regel te verspillen zoals ik deed met mijn_model = @model ?
toegevoegd de auteur m33lky, de bron