目标:当cards_controller运行def update
操作时,从Controller(cards_controller.rb)动态更新另一个Model的属性(Tracker)。
我收到错误:CardsController#update中的NameError,它调出了第二行的最后一行 def update_tracker(card_attribute):
updated_array = @tracker.instance_variable_get("#{string_tracker_column}")[Time.zone.now, @card.(eval(card_attribute.to_s))]
感知问题:除了在使用动态属性时我不知道正确“调用”Tracker属性的适当方法时,我已经完成了所有工作。
Tracker的属性是一个数组(使用PG作为db工作正常),我想
使用cards_controller.rb中的以下代码
if @card.deck.tracked
使进程启动cards_controller.rb
...
def update
@card = Card.find(params[:id])
if @card.deck.tracked
detect_changes
end
if @card.update_attributes(card_params)
if @card.deck.tracked
prop_changed?
end
flash[:success] = "Card info updated."
respond_to do |format|
format.html { render 'show' }
end
else
render 'edit'
end
end
...
private
def detect_changes
@changed = []
@changed << :front if @card.front != params[:card][:front]
@changed << :hint if @card.hint != params[:card][:hint]
@changed << :back if @card.back != params[:card][:back]
end
def prop_changed?
@changed.each do |check|
@changed.include? check
puts "Following property has been changed : #{check}"
update_tracker(check)
end
end
def update_tracker(card_attribute)
tracker_attribute = case card_attribute
when :front; :front_changed
when :back; :back_changed
when :hint; :hint_changed
end
string_tracker_column = tracker_attribute.to_s
@tracker ||= Tracker.find_by(card_id: @card.id)
updated_array = @tracker.instance_variable_get("#{string_tracker_column}")[Time.zone.now, @card.(eval(card_attribute.to_s))]
@tracker.update_attribute(tracker_attribute, updated_array)
end
修改:为了清晰起见,这里是app / models / tracker.rb:
class Tracker < ActiveRecord::Base
belongs_to :card
end
答案 0 :(得分:1)
从您的错误看,您的问题似乎是:
@tracker.instance_variable_get("#{string_tracker_column}")
在字符串插值后计算结果:
@tracker.instance_variable_get("front_changed")
这是instance_variable_get
的错误使用。它需要@
前置:
@tracker.instance_variable_get("@front_changed")
如果在Tracker模型上设置instance_variable_get
,则似乎不需要使用attr_reader :front_changed
。
答案 1 :(得分:1)
您对instance_variable_get
的使用已得到纠正,但是这种方法注定会失败,因为ActiveRecord列值不会存储为单个实例变量。
您可以使用
@tracker[string_column_changed]
@card[card_attribute]
按名称检索属性值。如果您想获得关联,请使用public_send
。如果存在包含列值的访问器(例如载波),后者也很有用