Goal: dynamically update another Model's properties (Tracker) from Controller (cards_controller.rb), when cards_controller is running the
def update
action.
Error I receive : NameError in CardsController#update, and it calls out the 2nd last line in the def update_tracker(card_attribute) :
updated_array = @tracker.instance_variable_get("#{string_tracker_column}")[Time.zone.now, @card.(eval(card_attribute.to_s))]
Perceived problem: I have everything working except that I don't know the appropriate way to 'call' the attribute of Tracker correctly, when using dynamic attributes.
The attribute of the Tracker is an array (using PG as db works fine), I want to
- figure out what property has been changed (works)
- read the corresponding property array from Tracker's model, and make a local var from it. (works I think, )
- push() a new array to the local var. This new array contains the datetime (of now) and, a string (with the value of the updated string of the Card) (works)
- updated the Tracker with the correct attribute.
With the following code from the cards_controller.rb
- it's the
if @card.deck.tracked
in the update method that makes the process start
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
Edit: For clarity here's the app/models/tracker.rb:
class Tracker < ActiveRecord::Base
belongs_to :card
end