ruby-on-rails – How to use attr_accessible in Rails 5?

Question:

How to use attr_accessible (maybe there is an analogue) in Rails 5? The protected_attributes gem does not work as there is a conflict with the activemodel and activerecord versions. Thanks in advance.

Answer:

This attribute does not work in modern versions of the Ruby on Rails framework. Previously, it was used in order to explicitly set attributes at the level of the model, which can be "massively" edited at the controller level (that is, in the group of parameters that come from the form). This practice is recognized as unsuccessful, firstly, you implicitly allow editing for all controllers, of which there can be many (at least the application and the administration system), and secondly, at the model level, you explicitly grant permissions that should be issued at the controller level. Thirdly, too loose use of this attribute (both for the backend and for the frontend parts of the application) led to application vulnerabilities, when from the frontend part it was possible, by manipulating the content of the POST content, to change those model parameters that were not allowed to change from the frontend part, but which were allowed in attr_accessible for example for the backend part of the site.

Starting with Ruby on Rails 4, the permission to assign parameters to the current model has been moved from the model level to the controller level. Now you need to explicitly specify which parameters are allowed to be changed in the model at the controller level. For example, one of the possible options might look like this

class SomeController < Admin::ApplicationController
  ...
  def create
    resource = Resourse.new
    resource.assign_attributes(resoure_params)
    if resource.save
      redirect_to index_page
    else
      render resource.new_record? ? :new : :edit
    end
  end
  ...
  private

  def resourse_params
    [ :id, :name, :weight ]
  end
  ...
end

or you can explicitly go through the parameters, mark with the permit method those that can be passed to the model and use, for example, the create method

class SomeController < Admin::ApplicationController
  ...
  def create
    if Resourse.create resource_params
      redirect_to index_page
    else
      render resource.new_record? ? :new : :edit
    end
  end
  ...
  private

  def resource_params
    params.require(:resource).permit(:id, :name, :weight)
  end
  ...
end
Scroll to Top