has_many throughの関係にある中間テーブルの、fields_forのフォームに埋め込む内容を、新規ウィンドウのポップアップで選択した値を反映させたいと思っております。
こういった実装なので、ポップアップから戻ってくると親ウィンドウのグローバル変数は空になってしまうため、上手く連携できません。
form_tagで親モデルとは切り離した実装にするしかないでしょうか。
できるだけfields_forを用いたいと思ってます。
また、チェックボックスで別窓で選んだ値をちゃんと、@post.usersで呼び出せるようにするためには、どのタイミングでどういった記述が必要でしょうか。
問題点:
・中間テーブルのidを選ばせるだけでなく、中間テーブルにmemoというテキスト要素があり、こちらも編集の必要があるため、collection_check_boxesやnested_form等、IDだけを選ばせるものが利用できない
・ポップアップから戻って来る際に、親ウィンドウ側のform_forのf変数は空っぽになるので、f.fields_forができない
不明点:
・紐づけたいusers_posts の値を削除、追加する場合、@post.usersでDB保存前の要素をチェックボックで選択したものにどのタイミングで挿入させることができるのか?
・create, updateの @post.save!で、今回追加・削除するusers_posts関連テーブルのバリデーションチェックも一度に行えるか?
※以下は参考までにこんな感じ、で書いているソースなので細かいエラーがあったらスミマセン…
model
所持カラム
id, titie, contents ...
lang
1class Post < ActiveRecord::Base 2 has_many :posts_users 3 has_many :authors, :through => :posts_users 4 validates :title, presence: true 5 accepts_nested_attributes_for :users 6end
所持カラム
id, name, email
lang
1class User < ActiveRecord::Base 2 has_many :posts_users 3 has_many :posts, :through => :posts_users 4end
所持カラム
user_id, post_id, memo
lang
1class UsersPost < ActiveRecord::Base 2 belongs_to :post 3 belongs_to :user 4 validates :memo, presence: true 5end
メインの選択部分
view
app/views/posts/_form.html.erb
lang
1<%= form_for(@post) do |f| %> 2 <%= f.text_field :title %> 3 ..... 4 <%= render "form_posts", f: f %> 5 .... 6 <%= f.submit "登録" %> 7<% end %>
メイン選択部分で別ウィンドウで選んだ中間テーブルの結果と、中間テーブルのmemo要素を更新するフォーム(ajax対応)
app/views/posts/_form_posts.html.erb
locals f
lang
1<div id="_posts"> 2 # ここの@postと、f が、別ウィンドウから選択して戻ったときに消えてしまう 3 # @post.usersで、選択した中間テーブルの内容を呼べる方法が分からない 4 <% @post.users.each do |user| %> 5 <%= f.fields_for :users, user do |user_field| %> 6 <%= user.name %> / 7 <%= author_field.text_field :memo %> 8 <% end %> 9 <% end %> 10</div> 11<%= link_to "検索", select_users_posts_path, :target => "_blank" %>
別ウィンドウの中間テーブルID選択部分の表示部
app/views/posts/select_users.html.erb
lang
1<%= form_for(url: set_users_posts_path) %> 2 <% @users.each do |user| %> 3 <% check_box_tag "check_user_id[]", user.id %> 4 <% end %> 5 <%= submit_tag "送信" %> 6<% end %>
jsファイル
lang
1app/views/set_users.js.erb 2$('#_posts').html('<%= j( render( 'form_posts' ) ) %>');
controller
app/controllers/posts_controller.rb
lang
1before_action :set_post, only: [:edit, :update] 2 3def new 4 @post = Post.new 5end 6 7def edit 8 @post = Post.find(params[:id]) 9end 10 11def create 12 @post = Post.new(post_params) 13 begin 14 # ここの処理で、Postのみでなく、UsersPostのバリデーションも一括でチェックしたい 15 @post.save! 16 rescue 17 render "new" 18 end 19end 20 21def update 22 @post.attribute = post_params 23 begin 24 @post.save! 25 rescue 26 render "edit" 27 end 28end 29 30def select_users 31 @users = User.all 32end 33 34def set_users 35 @users = User.where(id: params[:check_user_id]) 36 # ここで、チェックボックスで選択した中間テーブルを@post.usersで保存無しで呼べるような処理を書きたい 37end 38 39private 40 def set_post 41 @post = Post.find(params[:id]) 42 end 43 44 def post_params 45 params.require(:post).permit(:title, :msg, authors_attributes: [:memo]) 46 end
あなたの回答
tips
プレビュー