Обновление нескольких моделей с помощью одной формы в Rails

#ruby-on-rails #model-view-controller #associations #fields-for

#ruby-on-rails #модель-представление-контроллер #ассоциации #поля — для

Вопрос:

Я новичок в Rails и пытаюсь создать форму, которая позволяет пользователям заполнять и отправлять форму. Форма завершает их профиль. Я хочу, чтобы форма обновляла Users модель (и таблицу базы данных), а также Interests модель (хобби). Я использую форму с. fields_for

Однако отправка формы не обновляет Interests модель. Он либо обновляет только User модель, либо возвращает различные ошибки (следующая Interest user must exist ошибка):

Модели:

 class User < ApplicationRecord
    has_many :interests, foreign_key: "interests_user_id"
    accepts_nested_attributes_for :interests
    
end

class Interest < ApplicationRecord
    belongs_to :user

    self.primary_key = "interest_id"

    
end
  

КОНТРОЛЛЕР:

 class UsersController < ApplicationController
      
      def index
        @allUsers = User.all

      end

      def new
        @user = User.new
        @user.interests.build
        
      end

      def create
    @user = User.new permitted_params

    =begin
        @user = User.new(
                :author => params[:user][:author],
                :user_name => params[:user][:user_name],
                :user_bio => params[:user][:user_bio],
            )

    @user.interests.new(
      :interest_name => params[:user][:interests_attributes][:interest_name],
      :interest_experience_level => params[:user][:interests_attributes][:interest_experience_level],
      :interest_positon => params[:user][:interests_attributes][:interest_positon],


      )
    =end

        if @user.save
            redirect_to users_url

        else
            render 'new'

            end
            
          end
    
    
    
        private
    
            def permitted_params
              #params.require(:interest).permit(User.attribute_names.map(amp;:to_sym),interest.attribute_names.map(amp;:to_sym))
    
              params.require(:user).permit(User.attribute_names.map(amp;:to_sym), interests_attributes: [:interest_name,:interest_experience_level,:interest_positon])
    
    
            end
    
    end
  

ФОРМА:

  <%= form_with model: @user do |newUser| %>
            <% if @user.errors.any? %>
                <ul>
                    <% @user.errors.full_messages.each do |message| %>
                        <li> <%= message %></li>
                    <%end%>
                </ul>
            <%end%>

            <div class="form-sections" id="user-profile">
                <h3>General Information</h3>
                <table class="formTables" id="formMainInfo">

                    <%= newUser.hidden_field :author, value:1 %>
                
                    <tr class="formRows">
                        <td class="formDescriptionCol"><%= newUser.label :user_name, "Your Name" %></td>
                        <td class="formInputCol">
                            <%= newUser.text_field :user_name %>
                        </td> 
                    </tr>
                    
                    
                    <tr class="formRows">
                        <td class="formDescriptionCol"> <%= newUser.label :user_bio, "Biography" %></td>
                        <td class="formInputCol">
                            <%= newUser.text_area :user_bio %>
                        </td> 
                    </tr>
                    
                    
                <h3>Interests</h3>


                    <%= newUser.fields_for :interests do |newInterest| %>
                        <tr class="interestRows">
                            <td >Interest Name:</td>
                            <td>
                                <%= newInterest.text_field :interest_name%>
                            </td> 
                        </tr>
                        <tr class="interestRows">
                            <td ><%=newInterest.label :interest_experience_level, "Experience Level" %></td>
                            <td >
                                <%= newInterest.text_field :interest_experience_level %>
                            </td> 
                        </tr>
                        <tr class="interestRows">
                            <td ><%= newInterest.label :interest_position, "Position" %></td>
                            <td >
                                <%= newInterest.text_field :interest_position %>
                            </td> 
                        </tr>
                        
                        
                    <%end%>
            
                </table>
            </div>
            
            <div class="formSections" id="buttonsSection">
                <%= newUser.submit "submit" %>
            </div>



        <%end%>
  

СХЕМА:

 create_table "interests", primary_key: "interest_id", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer "interest_user_id", null: false
    t.string "interest_name", limit: 45, null: false
    t.string "interest_experience_level", limit: 45, null: false
    t.string "interest_position", limit: 45, null: false
    t.index ["interest_user_id"], name: "user_id_idx"
  end


create_table "users", primary_key: "user_id", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string "user_name", limit: 60, null: false
    t.string "author", limit: 60, null: false
    t.string "user_bio", limit: 500, null: false
   
  end


  add_foreign_key "interests", "users", column: "interest_user_id", primary_key: "user_id", name: "interest_user_name", on_update: :cascade, on_delete: :cascade
  

Комментарии:

1. github.com/thiaguerd/rails_complex_forms_with_nested_attributes может быть, этот пример поможет вам

2. Будьте осторожны, используя params.require(:user).permit(User.attribute_names.map(amp;:to_sym), in permitted_params . Похоже, это отличный способ выстрелить себе в ногу.

3. Я бы действительно задался вопросом, почему вы усложняете себе задачу, добавляя префиксы к столбцам в таблице интересов. Просто придерживайтесь соглашения, если у вас действительно нет причины.

4. Я не понимаю, что вы имеете в виду, макс. «префикс столбцов». Я пытаюсь узнать, что такое соглашение. До сих пор моя работа / решение заключалась в добавлении optional: true к модели интереса.

5. Все столбцы в interests таблице имеют префикс — interest_user_id , interest_id . Что является излишним и действительно непоследовательным. Либо префикс все — или ничего. Наличие только одной таблицы с префиксом просто сбивает с толку. В Rails соглашение заключается в том, что префикс является глупым, и мы этого не делаем.