【Rails】fields_for를 사용하여 동일한 폼으로 다른 모델 객체를 편집합니다.
19079 단어 Rails초보자용form_withfields_for루비
fields_for란?
전제:
fields_for 구현
그럼 구현해 갑니다!
모델 설명
👇
accepts_nested_attributes_for
에 allow_destroy: true
를 전달하면 연관된 개체가 삭제됩니다. 아래에 기재되어 있지 않지만, reject_if: all_blank
를 추가하면, 공란의 경우에 데이터 갱신하지 않게 할 수도 있습니다. 옵션에 대해서는 상황에 맞추어 조사해 보면 좋네요.app/models/post_recipe.rb
#一対多のアソシエーション
has_many :procedures, dependent: :destroy
has_many :ingredients, dependent: :destroy
#関連付けしたモデルを一緒にデータ保存できるようにする
accepts_nested_attributes_for :procedures, allow_destroy: true
accepts_nested_attributes_for :ingredients, allow_destroy: true
app/models/ingredient.rb
#一対多のアソシエーション
belongs_to :post_recipe
app/models/procedure.rb
#一対多のアソシエーション
belongs_to :post_recipe
컨트롤러 설명
👇 스트롱 파라미터에
◯◯_attributes
와 같이 기술해, 아이 모델의 컬럼도 허가하도록(듯이) 합니다. 모델에 allow_destroy: true
를 작성하는 경우 _destroy 키를 스트롱 매개 변수에 추가합니다. 이 근처의 거동에 대해서는, Rails Guide 에 기술이 있으므로, 확인해 보세요.※필요한 곳만 꺼내서 쓰고 있습니다
app/controllers/post_recipes_controller.rb
def new
@post_recipe = PostRecipe.new
end
def create
@post_recipe = PostRecipe.new(post_recipe_params)
if @post_recipe.save
redirect_to post_recipe_path(@post_recipe), notice: "レシピを投稿しました!"
else
render :new, alert: "登録できませんでした。お手数ですが、入力内容をご確認のうえ再度お試しください"
end
end
private
def post_recipe_params
params.require(:post_recipe).permit(
:user_id,
:title,
:introduction,
:recipe_image,
:serving,
procedures_attributes: [:body, :_destroy],
ingredients_attributes: [:name, :amount, :_destroy]
)
end
뷰 설명
app/views/new.html.erb
<div class="container mt-4 align-imtes-center">
<div class='bg-light mx-auto mb-5'>
<%= form_with model: @post_recipe, local:true do |f| %>
(中略)
<!------------ 材料登録欄 -------------->
<div class="row">
<div class="form-inline mb-2">
<h4 class="mb-0">材料</h4>
<%= f.text_field :serving, placeholder: "何人分", size:"10x3", class:'ml-4' %>
</div>
</div>
<div class="row">
<table class="table table-borderless mb-0" id="ingredient-table">
<thead>
<th class="pb-1"><h6 class="mb-0">材料・調味料</h6></th>
<th class="pb-1"><h6 class="mb-0">分量</h6></th>
</thead>
<tbody>
<%= f.fields_for :ingredients do |ingredient| %>
<tr>
<td style="width: 12%" class="py-1"><%= ingredient.text_field :name, placeholder: "例)にんじん" %></td>
<td style="width: 10%" class="py-1"><%= ingredient.text_field :amount, placeholder: "例)一本" %></td>
<td class="align-middle p-0"><input type="button" value="削除" onclick="deleteRow(this)"></td>
</tr>
<% end %>
</tbody>
</table>
<input type="button" value="材料を追加" onclick="addRow('ingredient-table')" class="btn btn-sm btn-color py-0 my-3 ml-2">
</div>
<!------------ 作成手順登録欄 -------------->
<div style='max-width: 680px' class="mt-3 px-5 pt-4 mx-auto border-0">
<div class="row">
<h4 class="text-center mx-auto mb-0">つくり方</h4>
</div>
<div class="row">
<table class="table table-borderless" id="procedure-table">
<%= f.fields_for :procedures do |procedure| %>
<tr>
<td style='width: 70%' class="px-0"><%= procedure.text_area :body, placeholder:"手順を記入", size:'80 x 3', class:'p-2' %> </td>
<td class="align-middle"><input type="button" value="削除" onclick="deleteRow(this)"></td>
</tr>
<% end %>
</table>
<input type="button" value="手順を追加" onclick="addRow('procedure-table')" class="btn btn-sm btn-color py-0 mb-3">
</div>
</div>
<div class="row mt-4 pb-5">
<div class="form-inline mx-auto">
<%= f.submit 'レシピを公開', :name => 'post', style: 'font-size: 20px', class:'mr-5 btn btn-sm btn-warning text-white' %>
<%= f.submit '下書きに保存', :name => 'update', style: 'font-size: 20px', class:'mr-5 btn btn-sm btn-outline-secondary' %>
</div>
</div>
<%= f.hidden_field :user_id, :value => current_user.id %>
<% end %>
</div>
</div>
유효성 검사
여기가 빠진 곳이었습니다만, 여러가지 조사해 시행착오한 결과는 매우 심플했습니다 👇
모델 설명
👇 우선 부모 모델 쪽에 이렇게 기술해 줍니다.
※필요한 곳만 꺼내서 쓰고 있습니다
app/post_recipe.rb
with_options presence: true do
validates :recipe_image
validates :serving
validates :title
validates :introduction
validates :ingredients
validates :procedures
end
validates :title, length: { maximum: 14 }
validates :introduction, length: { maximum: 80 }
새 게시시 ingredients 테이블은 두 개의 열(name과 amount)을 fields_for로 업데이트하므로
ingredient.rb
에는 각 열에 대한 검증을 지정해 둡니다 👇app/ingredient.rb
belongs_to :post_recipe
with_options presence: true do
validates :name
validates :amount
end
procedures 테이블은 이번, 갱신 대상이 1 컬럼(body)만이므로, 원래의 기술인 채로 문제 없게 동작합니다👇
app/models/procedure.rb
#一対多のアソシエーション
belongs_to :post_recipe
이상입니다! !
Reference
이 문제에 관하여(【Rails】fields_for를 사용하여 동일한 폼으로 다른 모델 객체를 편집합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/mi-1109/items/82bde86493072e2dd2a4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)