accepts_nested_attributes_for 방법으로 하위 테이블 편집 & 싫어하는 기록 삭제 방법

하고 싶은 일


단어장 프로그램에서 한 과목에 등록된 단어를 편집하고 삭제하는 기능을 실현하였다

전제 조건


부모 테이블:subject(과목)
하위 테이블:word, 주요 열: "face", "flip"
워드를 편집할 때subject의 편집 화면으로 옮기려면subject모델의 실례와word모델의 실례,rails의acceptsnested_attributes_for 방법을 전제로 하다
form_for 방법을 통해 편집 화면에서 각 실례에hidden 형식의 input 라벨로 실례의 id를 삽입하여 산열 매개 변수에 저장하고 발송합니다.

작은 지식


allow_Destroy: 모형의attributes 방법에 진짜 옵션을 추가하면1이 있는 매개 변수에 대응하는 데이터베이스 실례가 삭제되었습니다.
View 측 적절히 매개변수 설정Destroy:1 추가 방법이 있습니다. 이번에는reject입니다.제가 if를 다루는 방법을 알려드리고 싶어요.

전송된 매개변수 구조


"subject"=>{
"title"=>"国語", 
"words_attributes"=>{
 "0"=>{"face"=>"テスト", "flip"=>"してます", "id"=>"54"}, // wordインスタンスの表データ
 "1"=>{"face"=>"", "flip"=>"", "id"=>"55"}, // wordインスタンスの裏面データ。この欄はView側で削除した。 こいつに該当するDBのレコードを消したい!
 "2"=>{"face"=>"明日は", "flip"=>"最高だ"}, //編集画面で新しく追加したインスタンスなのでidがない
 "3"=>{"face"=>"", "flip"=>""}}}, // 新しく作成したデータだが、何もデータが入っていない
"id"=>"35"} //subjectのid

가장 전하고 싶은 거.


이번 최대 난관은 카드를 없앨 때 그걸 어떻게 방법적으로 인식해 SQL로 Delete문을 발간하느냐다.

답안 코드


Model


class Subject < ApplicationRecord
  belongs_to :user
  has_many :words, dependent: :destroy
  accepts_nested_attributes_for :words, reject_if: :reject_both_blank, allow_destroy: true
  validates :title, presence: true

  def reject_both_blank(attributes)
    if attributes[:id]
      attributes.merge!(_destroy: "1") if attributes[:face].blank? and attributes[:flip].blank?
      !attributes[:face].blank? and attributes[:flip].blank?
    else
      attributes[:face].blank? and attributes[:flip].blank?
    end
  end
end

Controller


before_action :set_subject, only: [:show, :edit, :update]

def update
    @subject.update(create_params)
    redirect_to "/"
end

private
def create_params
  params.require(:subject).permit(:title, words_attributes: [:face, :flip, :id, :_destroy]).merge(user_id: current_user.id)
end

def set_subject
  @subject = Subject.find(params[:id])
end

모델 섹션의 설명


1


accepts_nested_attributes_for :words, reject_if: :reject_both_blank, allow_destroy: true
위 코드로,rejectboth_blank 함수에 트루가 나타나는 매개 변수는 발송 데이터에서 제외됩니다.

2


def reject_both_blank(attributes)
    if attributes[:id]

매개 변수의attributes에는 전송된 매개 변수가 포함되어 있습니다
"0"=>{"face"=>"テスト", "flip"=>"してます", "id"=>"54"}
아까의 예에서 위와 같은 녀석.
id 키가 존재하면, 새로 만든 실례가 아니면 다음 처리를 실행합니다.
```rb
attributes.merge!(_destroy: "1") if attributes[:face].blank? and attributes[:flip].blank?
!attributes[:face].blank? and attributes[:flip].blank?
```
만약 시계 안이 모두 비어 있다면 사용자가 삭제하고 싶은 데이터이기 때문에 삭제하는 메커니즘을 만들었다.attributes의 매개 변수destroy 키와 대응하는 값 1을 포함하는 산열을 추가합니다.

3


allow_destroy: True 옵션 불러오기
params의 매개 변수 목록에서Destroy: Delete 문은 SQL에서 재생되며 이 실례는 1개의 산열이 있는 매개 변수에 해당합니다.
이렇게 하면 해소할 수 있다.

외국


else
      attributes[:face].blank? and attributes[:flip].blank?
    end
참고로 매개 변수attributes에 id 키가 없으면 새로 만든 매개 변수이기 때문에 사용자는 이 단어를 워드의 실례로 저장하기를 원합니다.따라서 일반적인 프로젝트if 옵션에 병합된 함수와 같은 처리를 따라갑니다.
만약 시계 안이 모두 비어 있다면, 정말로 돌아갈 것이기 때문에, Rejectif 옵션 반응
"3"=>{"face"=>"", "flip"=>""}
위의 매개 변수는 서버 측에서 무시되고 데이터베이스에 저장되지 않습니다.

좋은 웹페이지 즐겨찾기