10

How can I use virtual attributes(getter, setter) in rails 4, as 'attr_accessible' removed.

I am getting issue, here

  def tags_list
    @tags = self.tags.collect(&:name).join(', ')
  end

I can reach above method, but not able to reach setter below, when trying to update/create.

  def tags_list=(tags)
    @tags = tags
  end
Ashwin Yaprala
  • 2,737
  • 2
  • 24
  • 56
  • 1
    Are you getting attr_accessible and attr_accessor mixed up? attr_accessible has gone - to be replaced by strong parameters. But as far as I know, attr_accessor remains. – Edward Apr 19 '13 at 17:18
  • sorry, Its attr_accessor :tags_list – Ashwin Yaprala Apr 19 '13 at 18:25
  • 2
    if you use attr_accessor you shouldn't need to define a getter or setter at all. attr_accessor is a macro that creates both of them for you. – Jake Hoffner Apr 19 '13 at 21:44
  • I am new in ruby on rails. My question is how to use virtual attributes in rails 4. – Ashwin Yaprala Apr 20 '13 at 12:46
  • 1
    This should help http://stackoverflow.com/questions/17135974/mongoid-w-rails-attr-accessible-no-method-found. I think you should not name your instance variable `@tags`, generally instance attributes with same name as getter are used by active record, `@tags_list` might be a better choice. – rubish Jul 04 '13 at 02:38
  • This should work in Rails 4 provided these aren't `protected` methods. The `attr_accessible` method has been deprecated because parameter validation is now done in the controller. – tadman Sep 06 '13 at 18:23

1 Answers1

13

Using virtual attributes in Rails 4 pretty much the same as with attr_accessible. You just have to add your virtual attribute to the permitted params in your controller (instead of attr_accessible), then add the getter and setter methods as usual in your model.

# your_controller.rb
private

def your_model_params
  params.require(:your_model_name).permit(:tags_list)
end
Chris Chattin
  • 482
  • 5
  • 7
  • 2
    But it does not work with #new and #create at the moment, which makes it pretty much useless, because you would have to write `your_virtual_attr=:something` separately all the time. Anyone else noticed this and has a clue on how to handle it? – phikes Aug 25 '14 at 21:08
  • 1
    I also noticed that calling `Tag.new(tags_list: [1, 2])` doesn't fire the `tags_list=()` virtual attribute.. is this a bug? – Feech Sep 05 '14 at 16:12
  • 1
    @phikes, is it just `before_action :your_model_params` ? You can optionally specfiy: , only: [:new, :create] or `exlcude: , except: [:action1, :action2, etc.]` . – atw Jun 11 '15 at 14:51