spassador
spassador

Reputation: 413

How to make a POST to a route from collection_select in helper Rails

I'm a newbie in Ruby on Rails. This is the helper method that I call from the html.

def select_user_role (user)
    @user = user
    collection_select(:user, :role, User.roles.to_a, :first, :first, {}, {
        data: {user_id: @user.id},
        onChange: ""
    })
end

The select works properly.

I would like to send a call to a route with some parameters in POST (like user id and role position) from the onChange. How am I supposed to do that?

The roles are defined as a enum in the User model.

Upvotes: 2

Views: 274

Answers (1)

Sebastián Palma
Sebastián Palma

Reputation: 33460

You can add a change event listener to your collection_select, and this way, whenever the user changes makes a change in the selection, then you can make your request to the method you need in the controller you need.

Give an id to your collection_select, and add the data attribute data-user (as example):

  <%= collection_select(
      :user, 
      :role_id, 
      User.roles, 
      :first, 
      :first,
      {},
      {'data-user': 1}
    ) %> # Skipping the "on-tag" onChange attribute

Then you can create an script to get the rendered select tag, add the change event listener, get the role and user values, and make an XMLHttpRequest, passing those values as JSON, in a POST request:

  <script>
    let role_select = document.getElementById('user_role_id')
    role_select.addEventListener('change', function() {
      let role = this.value,
          user = this.dataset.user,
          xhr = new XMLHttpRequest()

      xhr.open('POST', '/test', true)
      xhr.setRequestHeader('Content-Type', 'application/json')
      xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
          // Do whatever you want if it succeeds
        } else {
          // Do whatever you want if it doesn't succeed
        }
      }
      xhr.send(JSON.stringify({role_id: role, user_id: user}))
    })
  </script>

Upvotes: 2

Related Questions