Rails has_one, assign_to, join_table и вложенная форма - PullRequest
0 голосов
/ 05 апреля 2020

Я создаю User, Role и UserRole. Пользователь может создать список ролей, и из новой пользовательской формы есть вложенная форма, которая заполняет список созданных ролей, после чего пользователь может выбрать роль и связать ее с новым пользователем. Я могу создать список ролей, но столкнулся с проблемой при создании вложенной формы в новом файле представления пользователя.

Вот модели, пожалуйста, сообщите мне, если отношения правильные.

class User < ApplicationRecord
  has_one :user_role
  has_one :role, through: :user_role
end

class Role < ApplicationRecord
  has_many :user_roles
  has_many :users, through: :user_roles
end

class UserRole < ApplicationRecord
  belongs_to :user
  belongs_to :role
end

User контроллер. Я не уверен, что мой контроллер правильный:

def new
  @user = User.find_by_id(params[:id])
  @user = @current_user.account.users.new
  @user.build_user_role
end

def create
  @user = User.find_by_id(params[:id])                
  @user = @current_user.account.users.create_with_password(user_params)
    if @user.save
       redirect_to users_path
    else
       render 'new'
    end
end

private
def user_params
  params.require(:user).permit(:id, :email, :password, :password_confirmation, :admin, :owner, user_role_attributes: [:user_id, :role_id])
end

end

Ниже приведена новая пользовательская форма:

<%= form_for(@user, remote: true) do |f| %>

<%= f.text_field :email, class: "form-control", autofocus: true, autocomplete: "off" %>
<%= f.check_box :admin, class:"checkbox" %>
<%= f.check_box :owner, class:"checkbox" %>

<%= f.fields_for :user_role do |ff| %>
<%= ff.collection_select :role_id, @roles, :id, :role_name, include_blank: false %>
<% end %>             

<%= f.button "Create",  class: "btn btn-success" %>

<% end %>

Вложенная форма для user_role не отображается, а также пожалуйста, сообщите, если отношения между User, Role и UserRole верны.

1 Ответ

0 голосов
/ 05 апреля 2020

Если пользователь может когда-либо иметь только одну роль, вам, во-первых, не нужна таблица соединения user_roles:

class User < ApplicationRecord
  belongs_to :role
end

class Role < ApplicationRecord
  has_many :users
end

Хотя кажется довольно наивным предполагать, что вы не будете на самом деле хочу ассоциацию многих ко многим, что на самом деле намного более полезно Например:

class User < ApplicationRecord
  has_many :user_roles
  has_many :roles, through: :user_roles
end

class Role < ApplicationRecord
  has_many :user_roles
  has_many :users, through: :user_roles
end

class UserRole < ApplicationRecord
  belongs_to :user
  belongs_to :role
end

Вы также попадаете в общую ловушку для новичков, где путаете вложенные атрибуты с простым выбором ассоциации.

Вам не нужны @user.build_user_role или f.fields_for :user_role , Вам просто нужно выбрать и внести в белый список параметр role_id:

<%= form_for(@user, remote: true) do |f| %>
  # ...
  <%= f.collection_select :role_id, @roles, :id, :role_name, include_blank: false %>
  # ...
<% end %>

def new
  # why even do this if you are just reassigning it on the next line?
  @user = User.find_by_id(params[:id]) 
  @user = @current_user.account.users.new
end

def create
  @user = User.find_by_id(params[:id])
  # Violation of Law of Demeter - refactor!
  @user = @current_user.account.users.create_with_password(user_params)
  if @user.save
    redirect_to users_path
  else
    render 'new'
  end
end

private
def user_params
  params.require(:user)
        .permit(
          :id, :email, :password, 
          :password_confirmation, 
          :admin, :owner, 
          :role_id # this is all you really need
        )
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...