1

I'm upgrading my application from rails 3.2 to rails 4.2.5.

In one of my model i have attr_accessor :user_id and i have defined a getter and setter methods, as i need to value on conditional basic.

    class DummyModel < ActiveRecord::Base

        attr_accessor :user_id
        belongs_to :current_user
        before_save :set_user_id

        def user_id
            self[:user_id] ? self[:user_id] : current_user_id ? current_user.id : nil
        end

        def user_id=(value)
            self[:user_id] = value ? value : current_user_id ? current_user.id : nil
        end

        private

        def set_user_id
            self.current_user_id = CurrentUser.first_or_create(:user_id => self[:user_id]).id
        end
    end

In the above DummyModel, that table doesn't have user_id. But a referance current_user_id which needs to be update by the params user_id which i get from browser.

So when i do DummyModel.new(params[:dummy_model]), it will try to assign the params[:dummy_model][:user_id] to the attr_accessor (With the setter method = user_id=(value)). Once assigned it can be used in the before_save.

This whole thing was working properly in rails 3.2. But when i tried to update to rails 4.2, im getting this error message, as assigning value for attr_accessor with self[:user_id] syntax is removed.

    ActiveModel::MissingAttributeError: can't write unknown attribute `user_id`

So i have one solution to rename the user_id to something else, but user_id is used is many places of my application its not possible to change.

Hope this explains my problem. Thanks for the help in advance.

max
  • 347
  • 3
  • 14
  • can you show your full model with all `attr_accessible`, `attr_accessor`, associations and getters/setters definitions? – BoP Feb 20 '16 at 11:05
  • I think answer below from @FrederickCheung is correct one. – BoP Feb 20 '16 at 16:58

3 Answers3

2

I'm not sure why you're doing this but there's no point using attr_accessor if you're going to replace the methods it is generating. You may as well use the instance variable directly, for example

def user_id
  @user_id || current_user_id
end

def user_id=(value)
  @user_id = value || current_user_id
end
Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
1

If you prefer attr_accessible, you could use it in Rails 4 too. You should install it like gem:

gem 'protected_attributes'

What i can understand from the above but in rails 4 now there are strong parameters. attr_accessor still can be initialized in rails 4 and that still gives you virtual attributes, but from above it looks like user_id is a physical attribute on the model level. Let me know if this makes sense.

Muaaz Rafi
  • 1,469
  • 2
  • 15
  • 23
  • Thanks for the reply muaaz. I tried using protected_attributes too. My problem is using self[:user_id] instead of self.user_id. I cant use self.user_id because it will throw me stack level deep error. – max Feb 20 '16 at 09:39
  • Can you give me the error and have tried in that scope, plus whats the model name that will be helpful. – Muaaz Rafi Feb 20 '16 at 11:06
1

I think you are confused about rails 3 attr_accessible and attr_accessor.

Link about difference between them: https://stackoverflow.com/a/6958433/1306709

In rails 4 you still can use attr_accessor, but if you meant attr_accessible here is some info: strong parameters

Community
  • 1
  • 1
BoP
  • 417
  • 4
  • 12