Ruby on Rails Forms has_many с динамическими данными из другой модели - PullRequest
0 голосов
/ 25 апреля 2018

Основная цель здесь - разрешить каждой роли пользователей просматривать и редактировать только некоторые поля других пользователей. Но роли будут постоянно расти, поэтому они должны быть динамичными.

У меня проблемы с созданием новой роли со списком всех полей пользователя, даже если связь еще не существует.

enter image description here

Мне бы хотелось:

  <%= form.fields_for :role_assignment do |role_assignment_form| %>
    <tr>
      <td><%= role_assignment_form.text_field :user_field, disabled: true %></td>
      <td><%= role_assignment_form.check_box :show_permission, id: :role_show_permission %></td>
      <td><%= role_assignment_form.check_box :edit_permission, id: :role_edit_permission %></td>
    </tr>
  <% end %>

Чтобы загрузить как это:

User.attribute_names.map do |att|
  role.role_assignment.find_by_user_field(att) || RoleAssignment.new(role: @role,user_field: att)
end

Отображается только текущие регистры. Я даже не знаю, где поставить код выше ...

Диаграммы базы данных для Role и RoleAssignment:

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(12)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| id              | int(12)      | NO   | PRI | NULL    | auto_increment |
| id_role         | int(12)      | NO   |     | NULL    |                |
| user_field      | varchar(255) | NO   |     | NULL    |                |
| show_permission | tinyint(1)   | NO   |     | 0       |                |
| edit_permission | tinyint(1)   | NO   |     | 0       |                |
+-----------------+--------------+------+-----+---------+----------------+

Модель:

class Role < ApplicationRecord
  self.table_name = "role"
  has_many :user_role, foreign_key: :id_role
  has_many :user,  through: :user_role
  has_many :role_assignment, foreign_key: :id_role
  accepts_nested_attributes_for :role_assignment, :reject_if => :all_blank, :allow_destroy => true
end

class RoleAssignment < ApplicationRecord
  self.table_name = "role_assignment"
  belongs_to :role, foreign_key: :id_role
end

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018
Ход мыслей

@ fongfan999 очень помог!Но это полный ответ на конкретный вопрос:

/app/controllers/roles_controller.rb:

class RolesController < ApplicationController
  def edit
    role_assignment = @role.role_assignment

    blacklist_attributes = %w(encrypted_password email_token forgot_token token provider uid oauth_token oauth_expires_at)
    user_attributes = User.attribute_names - blacklist_attributes

    (user_attributes - role_assignment.pluck(:user_field)).each do |user_field|
      @role.role_assignment << RoleAssignment.new(user_field: user_field)
    end
  end
end

/app/views/roles/_form.html.erb:

<%= form_with(model: role, local: true) do |form| %>

  <div class="field">
    <%= form.label :name %>
    <%= form.text_field :name, id: :role_name %>
  </div>
  <% unless role.new_record? %>
    <div class="field">
      <table>
        <tr>
          <th>Field</th>
          <th>Show?</th>
          <th>Edit?</th>
        </tr>
        <%= form.fields_for :role_assignment do |role_assignment_form| %>
          <tr>
            <td><%= role_assignment_form.text_field :user_field, disabled: true %></td>
            <td><%= role_assignment_form.check_box :show_permission, id: :role_show_permission %></td>
            <td><%= role_assignment_form.check_box :edit_permission, id: :role_edit_permission %></td>
          </tr>
        <% end %>
      </table>
    </div>
  <% end %>

  <br>

  <div class="actions">
    <%= form.submit %>
  </div>

<% end %>

Затем я перенаправил кнопку сохраненияк форме редактирования:

format.html { redirect_to edit_role_path(@role), notice: 'Role was successfully created now you can edit the permissions.' }

И пользовательский опыт выглядит следующим образом:

enter image description here

Тогда:

enter image description here

Спасибо всем за помощь в ее решении.

0 голосов
/ 25 апреля 2018

Попробуйте следующее:

# app/controllers/roles_controller.rb
role_assignment = @role.role_assignment

# You might not show these attributes, right?
blacklist_attributes = %w(id created_at updated_at)
user_attributes = User.attribute_names - blacklist_attributes

# Do not build existing user fields
(user_attributes - role_assignment.pluck(:user_field)).each do |user_field|
  @role.role_assignment.build(user_field: user_field)  
end

Должны ли мы использовать role_assignments (форма множественного числа) вместо role_assignment (форма единственного числа) в :has_many?

...