ruby on rails - collection_check_boxes messes with update values - Stack Overflow

admin2025-05-01  2

In my Rails 5 project I have 3 models, User, Book, and UserBook. Basically the user_books table is a connecting table connecting users to books.

This is my UserBook model

class UserBook < ApplicationRecord
  belongs_to :user
  belongs_to :book
end

This is my Book model

class Book < ApplicationRecord
  has_many :user_books
end

And lastly this is my user model

class User < ApplicationRecord    
  has_many :user_books
  has_many :books, through: :user_books
  before_update :set_user

  private

  def set_user
    return unless User.current

    self.updated_by = User.current
  end
end

My controller action is as follows

  class UserController < BasicCrudController
    def update
      if user.update(user)
        redirect_to user_path(user), notice: 'User was successfully updated.'
      else
        render :edit
      end
    end

    private

    def user
      @user ||= User.build(params[:user])
    end

    def user_params
      params.require(:user).permit(:name, book_ids: [])
    end
  end

This setup was working fine until I added the :book_ids in my params. Then the updated_by started getting set to blank on update if I update :book_ids. Upon research I confirmed that if there's a collection before_update is not triggered.

I therefore tried to merge updated_by to params by various methods. Example:

def user_params
  params.require(:user).permit(:name, book_ids: []).tap do |whitelisted|
    whitelisted[:updated_by_id] ||= current_user.id
  end
end

No matter what I try however it seems just updating the values of book_ids automatically set updated_by_id to nil

What's going on? And how can I fix this problem?

In my Rails 5 project I have 3 models, User, Book, and UserBook. Basically the user_books table is a connecting table connecting users to books.

This is my UserBook model

class UserBook < ApplicationRecord
  belongs_to :user
  belongs_to :book
end

This is my Book model

class Book < ApplicationRecord
  has_many :user_books
end

And lastly this is my user model

class User < ApplicationRecord    
  has_many :user_books
  has_many :books, through: :user_books
  before_update :set_user

  private

  def set_user
    return unless User.current

    self.updated_by = User.current
  end
end

My controller action is as follows

  class UserController < BasicCrudController
    def update
      if user.update(user)
        redirect_to user_path(user), notice: 'User was successfully updated.'
      else
        render :edit
      end
    end

    private

    def user
      @user ||= User.build(params[:user])
    end

    def user_params
      params.require(:user).permit(:name, book_ids: [])
    end
  end

This setup was working fine until I added the :book_ids in my params. Then the updated_by started getting set to blank on update if I update :book_ids. Upon research I confirmed that if there's a collection before_update is not triggered.

I therefore tried to merge updated_by to params by various methods. Example:

def user_params
  params.require(:user).permit(:name, book_ids: []).tap do |whitelisted|
    whitelisted[:updated_by_id] ||= current_user.id
  end
end

No matter what I try however it seems just updating the values of book_ids automatically set updated_by_id to nil

What's going on? And how can I fix this problem?

Share Improve this question asked Jan 2 at 17:35 mratebmrateb 2,5096 gold badges31 silver badges64 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

You could use collection_check_boxes in your form to allow multiple selections. For example, if you have a User model and a Book model, and you want to assign books to a user:

<%= form_for @user do |f| %>
  <%= f.collection_check_boxes :books_ids, Book.all, :id, :name %>
  <%= f.submit %>
<% end %>
  • :books_ids is the attribute that will store the selected books IDs.
  • Book.all is the collection of books to display.
  • :id is the value to be sent as the parameter.
  • :name is the label to display for each checkbox.

strong params for your controller: params.require(:user).permit(:name, ..., ..., books_ids: [])

https://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_check_boxes

转载请注明原文地址:http://www.anycun.com/QandA/1746104757a91734.html