Thibaud Clement
Thibaud Clement

Reputation: 6897

Rails 4 has_many through: update join model from parent model edit view

In my Rails 4 app, I have the following models:

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
  has_many :posts
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

I mainly use the Administration join model to define a role for each user in each calendar.

So, when a user creates a calendar, or when a user joins a calendar, a new row is created in the Administration model, with the user_id, the calendar_id and the associated role.

All of this has been taken care of.

I also know how to delete a user or delete a calendar, which automatically deletes all the corresponding administrations thanks to the dependent: :destroy option added in both models.

Now, what I am interested in is how I can update the role of a user for a given calendar, in this particular calendar edit view.

Note: in this particular situation, a user's role is either set to Editor or Viewer, and can only be updated to the other option.

So far, I have built this table to display the list of the users who belong_to the calendar:

<table id="manage_users">

  <tr>
    <th><span class="glyphicon glyphicon-user" aria-hidden="true"></span> NAME</th>
    <th><span class="glyphicon glyphicon-filter" aria-hidden="true"></span> ROLE</th>
    <th><span class="glyphicon glyphicon-time" aria-hidden="true"></span> JOINED</th>
    <th><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> OPTIONS</th>
  </tr>

  <% @calendar.users.each do |user| %>

    <tr>
      <% if user.id == current_user.id %>
        <td>You</td>
        <td><%= user.administrations.find_by_calendar_id(@calendar.id).role %></td>
        <td><%= user.administrations.find_by_calendar_id(@calendar.id).created_at.strftime("%B %d, %Y") %>
        </td>
      <% else %>
        <td><%= user.first_name %> <%= user.last_name %></td>
        <td><span class="glyphicon glyphicon-user" aria-hidden="true"></span> <%= user.administrations.find_by_calendar_id(@calendar.id).role %>
        </td>
        <td><%= user.administrations.find_by_calendar_id(@calendar.id).created_at.strftime("%B %d, %Y") %>
        </td>
        <% unless user.id == user.administrations.find_by_calendar_id(@calendar.id).role %>
          <td><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> Edit Role</td>
        <% end %>
      <% end %>
    </tr>

  <% end %>

</table>

Where I am struggling now is how to implement the edit role feature.

Should I have insert a kind of "inline form" with two radio buttons — one for Editor and the other for Viewer — with the current role checked by default?

Or should I go with the remote: true route with a JS alert?

Any suggestion would be appreciated.

Upvotes: 0

Views: 308

Answers (1)

x6iae
x6iae

Reputation: 4164

1) Get a method to handle this:

user.rb

def update_role(role)
  self.update_attributes(:role, role)
end

2) Get a controller action to handle this:

users_controller.rb

class UsersController << ApplicationController
  def update_role
    @user = User.find(params[:id])
    @user.update_role(params[:role)
  end
end

3) get a route to your controller action

route.rb

get "user/role/update" => "user#update_role"

4) point your radio_buttons' form to this controller action

<%= form_tag (url: "user/role/update" id: user.id), remote: true do %>

and put the radio button for role in this form, each with the separate types of roles there are.

NOTE: Since you are already familiar with the workings of most of this,much details are not given, Just some pointers on how you might approach this.

Hope this helps...

Upvotes: 1

Related Questions