2017-12-21 1 views
0

Ich habe eine ältere Datenbank mit einer Spalte ähnlich wie My#Column genannt, die ich alias versuche. In meinem Sequel Modell habe ich:Aliasing Spalte mit Hashtag in Namen in Rails

alias_attribute :MyColumn, :"My#Column" 

Aber ich bekomme einen Syntaxfehler:

...Ruby24-x64/lib/ruby/gems/2.4.0/gems/activesupport-5.1.4/lib/active_support/core_ext/module/aliasing.rb:26: syntax error, unexpected end-of-input, expecting keyword_end

Das Problem scheint die # zu sein. Ich habe versucht, es wie \# zu entkommen, aber ich bekomme die gleichen Fehler. Ich verstehe nicht, warum ich einen Syntaxfehler bekomme, da diese Art von Symbol an anderen Stellen für mich funktioniert hat.

Was kann ich tun, dieses Alias ​​an der Arbeit?

Antwort

1

Dies ist, was alias_attribute eigentlich Source

module_eval <<-STR, __FILE__, __LINE__ + 1 
    def #{new_name}; self.#{old_name}; end   # def subject; self.title; end 
    def #{new_name}?; self.#{old_name}?; end  # def subject?; self.title?; end 
    def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end 
    STR 

So im Wesentlichen ist dies immer

def MyColumn; self.My#Column; end 
    def MyColumn?; self.My#Column?; end 
    def MyColumn=(val); self.My#Column= val; end 

Hinweis darauf, dass dies in einer einzigen Zeile ist, was bedeutet, tut, dass alles nach self.My wird um einen Kommentar (einschließlich der end) und damit der Fehler, den Sie erhalten. Selbst wenn dies keine einzige Zeile in railsruby wäre würde einfach eine NoMethodError für die Tatsache, dass My ist keine Methode, weil der #Column Teil würde als ein Kommentar behandelt werden.

Dies scheint auch seltsam, da ActiveModel#alias_attribute eine funktionale Umsetzung der exakt gleichen über define_proxy_call hat, die wie

def define_proxy_call(include_private, mod, name, send, *extra) 
    defn = if NAME_COMPILABLE_REGEXP.match?(name) 
    "def #{name}(*args)" 
    else 
    "define_method(:'#{name}') do |*args|" 
    end 

    extra = (extra.map!(&:inspect) << "*args").join(", ".freeze) 

    target = if CALL_COMPILABLE_REGEXP.match?(send) 
    "#{"self." unless include_private}#{send}(#{extra})" 
    else 
    "send(:'#{send}', #{extra})" 
    end 

    mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1 
    #{defn} 
     #{target} 
    end 
    RUBY 
end 

Hier sieht können Sie sehen, es überprüft, um tatsächlich zu sehen, ob der neue Name (name) und ursprünglichen Namen (send) sind „compliable“ und wenn sie nicht behandelt sie entsprechend.

Anstatt alias_attribute die mit haben wird Fragen, was Charakter im Wesentlichen ein Kommentar. Ich würde vorschlagen, dasselbe unter Verwendung von public_send z.B.

def MyColumn 
    self.public_send("My#Column") 
    end 
    def MyColumn=(val) 
    self.public_send("My#Column=",val) 
    end 
    def MyColumn? 
    self.public_send("My#Column?") 
    end 

Dies sollte zu dem gleichen führen, aber ohne die Syntaxprobleme.

+0

Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu erklären. Ich habe ein oder zwei Dinge gelernt. Und es hat funktioniert. Prost! – JosephGage