Rails 6: Attaching Devise current_user.id to form submissions In my Ruby on Rails 6 app:

I have a User class built with Devise, and I scaffolded a List class where each List should belong_to a User. 

I want Lists created through my app to be automatically assigned to the logged-in user. This should happen on the back end, after the rest of the new List fields have been posted to the server.

I was able to make this happen by adding a line to the default list-params definition in the scaffolded controller:

def list_params
  params[:list].merge!(:user_id =&gt; current_user.id.to_s)
  params.require(:list).permit(:title, :active, :user_id)
end


My questions are: 


Am I reinventing the wheel somehow with this approach?
Does modifying the list_params in this way affect the application outside of creating and updating Lists?
Have I introduced any potential security issues by doing things this way?


For reference, here is the rest of the controller:

class ListsController &lt; ApplicationController
  before_action :authenticate_user!
  before_action :set_list, only: [:show, :edit, :update, :destroy]

# GET /lists
# GET /lists.json
def index
  @lists = List.all
end

# GET /lists/1
# GET /lists/1.json
def show
end

# GET /lists/new
def new
  @list = List.new
end

# GET /lists/1/edit
def edit
end

# POST /lists
# POST /lists.json
def create
  @list = List.new(list_params)

  respond_to do |format|
    if @list.save
      format.html { redirect_to @list, notice: "List was successfully created." }
      format.json { render :show, status: :created, location: @list }
    else
      format.html { render :new }
      format.json { render json: @list.errors, status: :unprocessable_entity }
    end
  end
end

# PATCH/PUT /lists/1
# PATCH/PUT /lists/1.json
def update
  respond_to do |format|
    if @list.update(list_params)
      format.html { redirect_to @list, notice: "List was successfully updated." }
      format.json { render :show, status: :ok, location: @list }
    else
      format.html { render :edit }
      format.json { render json: @list.errors, status: :unprocessable_entity }
    end
  end
end

# DELETE /lists/1
# DELETE /lists/1.json
def destroy
  @list.destroy
  respond_to do |format|
    format.html { redirect_to lists_url, notice: "List was successfully destroyed." }
    format.json { head :no_content }
  end
end

private

# Use callbacks to share common setup or constraints between actions.
def set_list
  @list = List.find(params[:id])
end

# Only allow a list of trusted parameters through.
def list_params
  params[:list].merge!(:user_id =&gt; current_user.id.to_s)
  params.require(:list).permit(:title, :active, :user_id)
end
end


And here is the form template:

&lt;%= form_with(model: list, local: true) do |form| %&gt;
    &lt;% if list.errors.any? %&gt;
      &lt;div id="error_explanation"&gt;
        &lt;h2&gt;&lt;%= pluralize(list.errors.count, "error") %&gt; prohibited this list from being saved:&lt;/h2&gt;

        &lt;ul&gt;
          &lt;% list.errors.full_messages.each do |message| %&gt;
            &lt;li&gt;&lt;%= message %&gt;&lt;/li&gt;
          &lt;% end %&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
    &lt;% end %&gt;

    &lt;div class="field"&gt;
      &lt;%= form.label :title %&gt;
      &lt;%= form.text_field :title %&gt;
    &lt;/div&gt;

    &lt;div class="field"&gt;
      &lt;%= form.label :active %&gt;
      &lt;%= form.check_box :active %&gt;
    &lt;/div&gt;


    &lt;div class="actions"&gt;
      &lt;%= form.submit %&gt;
    &lt;/div&gt;
  &lt;% end %&gt;
Why do we need user_id in params at all? Probably, there is a need to add some context to a current scope. And yes, you're trying to write straightforward logic in a different way.

Here is some suggested refactoring:

class ListsController &lt; ApplicationController
  def new
    build_resource
  end

  def create
    build_resource

    respond_to do |format|
      if update_resource
        # ...
      else
        # ...
      end
    end
  end

  def update
    update_resource
    # ...
  end

  def destroy
    destroy_resource
  end

  private

  def permitted_params
    params.require(:list).permit(:title, :active)
  end

  def resource
    @resource ||= current_user.lists.find(params[:id])
  end

  def build_resource
    @resource = current_user.lists.new
  end

  def update_resource
    resource.update(permitted_params)
  end

  def destroy_resource
    resource.destroy
  end
end


For those pure-CRUD controllers common logic can be easily moved into concern. We've created a gem some time ago https://github.com/cimon-io/unobtrusive_resources