вложенные атрибуты предварительно заполненные дочерние данные с пустым родителем - PullRequest
0 голосов
/ 03 октября 2019

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

Ассоциация

class User < ApplicationRecord
  has_one :account, foreign_key: :user_id

  accepts_nested_attributes_for :account
end

Class Account
  belongs_to :user
end

Теперь у меня есть форма на странице индекса панели управления.

<%= form_for @account, :url => account_path, html: { class: "abc" } do |f| %>
  <%= f.hidden_field :user_id, :value => current_user.id %>
  <%= f.fields_for :user do |user| %>
    <div class="medium-4 columns">
      <label>First Name</label>
      <%= user.text_field :first_name , class: 'xyz', data: {input: 'someinput'} %>
    </div>
    <div class="medium-4 columns">
      <label><b>Last Name<span class="invalid_message"> This field is required</span></b></label>
      <%= user.text_field :last_name, class: 'xyz', data: {input: 'someinput'} %>
    </div>
  <% end %>

  <div class="medium-4 medium-offset-2 columns">
    <label>Phone Number</label>
    <%= f.text_field :phone_number, class: 'xyz', data: {input: 'someinput'} %> 
  </div>
<% end %>

контроллер

 class AccountsController < ApplicationController

      def create
        @account = Account.new(account_params)
        if @account.save
          render json: {status: 'successfull'}
        else
          render json: {error: "#{@account.errors.full_messages}"}, status: 400
        end
      end

      private
      def account_params
        params.require(:account).permit(:phone_number, :user_id, user_attributes: [:first_name, :last_name])
      end
    end

    class DashboardController < ApplicationController

      def index
        ##I will always have current_user. For the account it will be blank for the first time
        if current_user.account.blank?
          @account = Account.new
        else
          @account = current_user.account
        end
      end
    end

Параметры

{"utf8"=>"✓", "authenticity_token"=>"asdasdadadadadsadadadadadQpy0tA82asdaalAgJsUcNk1i/kGETfZqnuQA==", "account"=>{"user_id"=>"123", "user"=>{"first_name"=>"sd", "last_name"=>"ad"}, "phone_number"=>"1212"}}

Есть две проблемы1) Имя и Фамилия не заполняются2) Параметры не идут правильно. Это должен быть account_attributes вместо account в параметре.

Примечание. В моем случае @account будет пустым в первый раз, но все же пользовательский объект (который является текущим пользователем) уже имеет first_name и last_name, которые Iнужно предварительно заполнить поля fields_for. Также мне нужен способ обновить имя и фамилию

Может кто-нибудь сказать мне, где я делаю не так

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

Наконец-то я нашел решение. Я делал пару вещей неправильно

1) В форме для этого должно быть @user вместо @account2) Затем в контроллере эта форма всегда будет отправлять его для обновления действия вместо создания. Причина в том, что у меня всегда будет current_user, поэтому rails автоматически проверит, существует ли объект (current_user), поэтому вместо отправки для создания он отправит действие update3) И наконец, при работе с однозначным сопоставлением нам нужно загрузить родительский объект и построить дочерний объект.

<%= form_for @user, :url => user_path, html: { class: "abc" } do |f| %>
    <div class="medium-4 columns">
      <label>First Name</label>
      <%= f.text_field :first_name , class: 'xyz', data: {input: 'someinput'} %>
    </div>
    <div class="medium-4 columns">
      <label><b>Last Name<span class="invalid_message"> This field is required</span></b></label>
      <%= f.text_field :last_name, class: 'xyz', data: {input: 'someinput'} %>
    </div>
  <%= f.fields_for :account do |account_info| %>
    <div class="medium-4 medium-offset-2 columns">
      <label>Phone Number</label>
    <%= account_info.text_field :phone_number, class: 'xyz', data: {input: 'someinput'} %> 
    </div> 
  <% end %>
<% end %>


class UsersController < ApplicationController

      def update
        if current_user.update(account_params)
          render json: {status: 'successfull'}
        else
          render json: {error: "#{@account.errors.full_messages}"}, status: 400
        end
      end

      private
      def account_params
        params.require(:account).permit(:first_name, :last_name, account_attributes: [:phone_number])
      end
    end

    class DashboardController < ApplicationController

      def index
        ##I will always have current_user. For the account it will be blank for the first time
        if current_user.account.blank?
           @account = current_user
           @account.build_account
        end
      end
    end
0 голосов
/ 03 октября 2019

Изменить @account = Account.new на @account = current_user.build_account. Вы должны увидеть поля, заполненные заранее.

...