views:

64

answers:

1

I have model called User with a has_many relationship to UserFilter. UserFilter has a belongs_to relationship to User.

Within the User model I have a method called update_user_filters(filter_params_array)

This method modifies user_filters like something like this

def update_user_filters(filter_params_array)
  new_filters = []
  old_filter = user_filters 

  filters_params_array.each do |filter_params|
    if filter_params[:id].blank? #if the filter does not yet exist
      new_filters << UserFilter.new(filter_params)
    end
  end
  user_filters = new_filters
end

This sets the user_filters to the expected value but upon saving it does not update the user_filters in the db.

however if I change the assignment to the following it does. Can someone explain why this is?

self.user_filters = new_filters

Note that when I first refer to user_filters in the model is does a select in the db so I am not sure how this local method is working differently with self and without self

+6  A: 

user_filters just creates a local variable. self.user_filters assigns it to the object. you probably want @user_filters = ....

Peter
So I am a little confused then. If user_filters and user_filters= are dynamically defined by active record will they not just work as methods? so calling user_filters I does actually call the method since I do not set it and it returns the records when called. Similarly I would expect user_filters= to call the method generated by active record also. But I guess what you are saying is that it is just creating a local variable? But how does user_filters have values if it is just a alocal variable. Note I have updated the code above to be more clear
Will
old_filters above now has an array list of filters so it seems that user_filters is not local. But yet when I call it the end it does act like a local variable per your previous comments
Will
This is a common point of confusion with Ruby. See, the Ruby interpreter does not know if "user_filters =" is setting a local variable or calling a method - so it does the former. This is why you need "self.user_filters =" to ensure it calls the method, not sets a local variable.
ryanb
here is a fairly detailed explanation http://www.rubyfleebie.com/use-self-explicitly/
Peer Allan
Thanks Peter, ryanb and Peer! It makes sense once you know why...
Will