0

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

Will
  • 8,102
  • 5
  • 30
  • 32
  • Related question: http://stackoverflow.com/questions/44715/why-do-ruby-setters-need-self-qualification-within-the-class – Greg Campbell Aug 18 '09 at 22:15

1 Answers1

6

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

Peter
  • 127,331
  • 53
  • 180
  • 211
  • 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 Aug 18 '09 at 21:12
  • 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 Aug 18 '09 at 21:14
  • 2
    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 Aug 18 '09 at 21:41
  • here is a fairly detailed explanation http://www.rubyfleebie.com/use-self-explicitly/ – Peer Allan Aug 19 '09 at 01:24