Вложенные модели Ruby on Rails не обновляются с помощью form_for, но нет ошибок при обновлении - PullRequest
0 голосов
/ 06 ноября 2018

Итак, в моем проекте rails у меня есть класс Patient, в котором есть один класс Лечение. Этот класс лечения имеет много DrNotes внутри него. Я все еще довольно новичок в рельсах, и я знаю, что это глубоко не рекомендуется в Rails, но я продолжаю использовать этот метод.

Моя проблема с редактированием DrNotes. Поскольку в процессе лечения есть много записей о врачах, я пытаюсь редактировать только одну конкретную заметку. Я использую Form_for для передачи параметров на заметку врача. Когда я отправляю форму, она перенаправляет меня на страницу, которая должна отображаться только после успешного завершения функции обновления. Однако ни одна из заметок фактически не обновляется, и при попытке выполнить обновление не выдается никаких ошибок.

Вот эти модели:

patient.rb

class Patient < ApplicationRecord
    has_one :treatment, dependent: :destroy

    accepts_nested_attributes_for :treatment, update_only: true

end

treatment.rb

class Treatment < ApplicationRecord
    belongs_to :patient

    has_many :dr_notes, class_name: "DrNote",
        foreign_key: "treatment_id", dependent: :destroy

    accepts_nested_attributes_for :dr_notes
end

dr_note.rb

class DrNote < ApplicationRecord
    belongs_to :treatment
end

В моем контроллере у меня есть:

Функция редактирования «Докторской записки»

def edit_dr_note
    @patient = Patient.find(params[:patient_id])
    @dr_note = @patient.treatment.dr_notes.find(params[:dr_id])
    @dr_note.update if @dr_note.nil?
end

Функция обновления «Докторской записки»

def update_dr_note
    @patient = Patient.find(params[:patient_id])
    @dr_note = @patient.treatment.dr_notes.find(params[:dr_id])
    if @dr_note.update(dr_note_params)
        redirect_to page_path(@patient)
    else
        flash.now[:error] = "Cannot update Doctor's notes"
        render 'edit_dr_note'
    end
end

Параметры врачебной записки

def dr_note_params
    params.require(:dr_note).permit(:id, :name, :message)
end

У меня есть: id в params.permit, потому что из исследований я слышал, что вам нужно включить его при обновлении моделей, но я не уверен, нужно ли это здесь.

У меня есть следующий код вways.rb

get '/pages/:patient_id/treatment/edit/edit_dr_note/:dr_id', to: 'pages#edit_dr_note', as: :edit_dr_note
match "pages/:patient_id/treatment/update/update_dr_note/:dr_id" => "pages#update_dr_note", as: :update_dr_note, via: [:patch, :post]

А в edit_dr_note.html.erb

<%= form_for @patient.treatment.dr_notes.find(params[:dr_id]), url: update_dr_note_path do |patient_form| %>

    <% @patient.treatment.dr_notes.each do |doctor| %>
    <% if doctor.id == @dr_note.id %>   #Only displays the fields for the desired note
        <%= patient_form.fields_for :dr_note, doctor do |doctor_fields| %>
            Name: <%= doctor_fields.text_field :name %>
            Message: <%= doctor_fields.text_field :message %>
        <% end %>
        <p>
            <%= patient_form.submit %>
        </p>
        <% end %>
    <% end %>
<% end %>

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Вы смешиваете два подхода ( вложенные ресурсы и вложенные атрибуты ). Используйте один, чтобы служить вашей цели.

С вложенными ресурсами:

<%= form_for [:pages, @patient, @treatment, @dr_note], url: update_dr_note_path do |dr_note| %>
  Name: <%= dr_note.text_field :name %>
  Message: <%= dr_note.text_field :message %>
  <p>
    <%= dr_note.submit %>
  </p>
<% end %>

Маршруты будут

get '/pages/:patient_id/treatment/:treatment_id/edit_dr_note/:dr_id', to: 'pages#edit_dr_note', as: :edit_dr_note
match "pages/:patient_id/treatment/:treatment_id/update_dr_note/:dr_id" => "pages#update_dr_note", as: :update_dr_note, via: [:patch, :post]

Измените edit_dr_note, чтобы определить @treatment

def edit_dr_note
  @patient = Patient.find(params[:patient_id])
  @treatment = @patient.treatment
  @dr_note = @patient.treatment.dr_notes.find(params[:dr_id])
  @dr_note.update if @dr_note.nil?
end

И, наконец, удалите accepts_nested_attribute_for из моделей, в этом подходе он вам не нужен.

С вложенными атрибутами:

Держите accepts_nested_attributes_for в моделях. И измените маршруты и форму, как показано ниже

get '/edit_dr_note/:dr_id', to: 'pages#edit_dr_note', as: :edit_dr_note
match "/update_dr_note/:dr_id" => "pages#update_dr_note", as: :update_dr_note, via: [:patch, :post]

И form_for

<%= form_for @patient, url: update_dr_note_path do |patient| %>
  <%= patient.fields_for :treatment do |t| %>
    <%= t.fields_for :dr_notes, @dr_note do |dr_note| %>
      Name: <%= dr_note.text_field :name %>
      Message: <%= dr_notetext_field :message %>
    <% end %>
  <% end %>
  <p>
    <%= patient.submit %>
  </p>
<% end %>

И измените метод dr_note_params, как показано ниже

def dr_note_params
  params.require(:patient).permit(:id, treatment_attributes: [:id, dr_notes_attributes: [:id, :name, :message])
end
0 голосов
/ 06 ноября 2018

Когда вы пишете следующую строку, вы пытаетесь find a DrNote, используя dr_id:

@dr_note = @patient.treatment.dr_notes.find(params[:dr_id])

Тогда как отношение dr_notes в Treatment, похоже, не определяет какого-либо конкретного поведения, и это ваша проблема.

Вам понадобится find_by идентификатор врача (или dr_id в вашем коде) и, таким образом, сначала определите отношение для DrNote.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...