over 2 years ago
> [阿芝解法](https://gist.github.com/tienshunlo/3b047979a2ac354e72be)

阿芝解法
最佳解法,單純用html的方法,成功用在select跟checkbox,還沒有成功試在radio上過。
(以後應該在new respond 的地方不用一題一題回答,可以一次送出去很多題,不過就qupid的商業模式好像也沒有必要一次送出去很多題)
radio好像只能用jQuery(JC解法)或無解。
不過,我需要的是,把在後台創建好的東西(issue跟option),放到前台讓user回答(option 跟 respond),所以(好像,目前還沒找到解法)不能用accepts_nested_attributes_for,常常都會發生有重複ID的問題。
在view的地方,還是沒辦法用rails helper (nested, fields_for )傳出去多道題目的答案,結果就是每個答案都有一樣的ID,變成只有一個答案。(可以看一下最下面還沒成功的:view/dashboard/respond/special_cates.html.erb)
因為accepts_nested_attributes_for好像通常都是用在輸入新的data(也就是說,我的後台應該可以用這個方法)。

Rails form with multiple nested models causes issues with radio groups
2009年的這篇,雖然好像可以,可是實際上也不知道有沒有解出來。

accepts_nested_attributes_for好像只能用在has_many,也可以用在has_many::through上
(參考這篇:accepts_nested_attributes_for with Has-Many-Through Relations)

記得select_tag要跟controller搭配好

models/profile_option.rb
class ProfileOption < ActiveRecord::Base
  belongs_to :profile
  belongs_to :option
end
models/profile.rb
class Profile < ActiveRecord::Base
  belongs_to :user
  #可以用的

  has_many :profile_option
  has_many :option, through: :profile_option, dependent: :destroy
  accepts_nested_attributes_for :profile_option
  #可以用的

  self.primary_key = 'user_id'
  GENDER_TYPES = [ "Male", "Female", "Do not wish to say" ]
end

備註:因為profile在設定的時候,沒有自己的id,主要是用user id當作primary_id,所以要加上self.primary_key = 'user_id'這行。

models/option.rb
class Option < ActiveRecord::Base
    belongs_to :issue
    has_many :respond,  :dependent => :destroy
    has_many :user,     through: :respond
    
    #可以用的

    has_many :profile_option
    has_many :profile,  through: :profile_option
    #可以用的

end

備註:@issues = SpecialCate.find(4).issue這個寫法,以後要記得改。

controllers/dashboard/profiles_controller.rb
class  Dashboard::ProfilesController < Dashboard::DashboardController 
  before_action :find_user
  before_action :set_profile
   
  
  
  
  def new
     @profile = @user.build_profile
     #id:4是登入類別

     @issues = SpecialCate.find(4).issue
    
     
  end
  
  
  def create
    @profile = @user.build_profile(profile_params)
    if @profile.save
      #@profile_option = @profile.profile_option.create(:id => current_user ,:profile_id => current_user)

      #redirect_to  dashboard_user_path(current_user)

      redirect_to unresponded_issue_dashboard_user_responds
      #redirect_to special_cates_dashboard_user_responds_path(current_user) 測試直接寫fields_for的方法寫respond,結果寫不出來

    else 
      render new
    end
  end
  
  def edit
   
  end
  
  def update
    
    
    
    ids = params[:profile][:profile_option_attributes].map{|t| t[:option_id]}
    #ids = (params[:ic_old] || {}).keys.map{|i|i.to_i}

    if ids.length > 0
      ProfileOption.where("profile_id =? AND option_id NOT IN (#{ids.join(',')})", @profile.id).delete_all
    else
      ProfileOption.where("profile_id = ?", @profile.id).delete_all
    end
    
    #更新舊的,不過這個APP不需要

    #@profile.profile_option.each do |f|

     # ic = ProfileOption.where(:profile_id => @profile.id, :id => f.id).first

      #if ic

       # ic.update_attributes(:option_id => f.option_id)

      #end

    #end

    
    #加入新的作法一

    params[:profile][:profile_option_attributes].each do |index|
      if !@profile.profile_option.map(&:option_id).include?(index[:option_id].to_i)
        ProfileOption.create(:profile_id => @profile.id, :option_id => index[:option_id])
      end
    end
    
    #加入新的作法二

    #params[:profile][:profile_option_attributes].each_with_index do |tar, index|

     # if !@profile.profile_option.map(&:option_id).include?(tar[:option_id].to_i)

      #  ProfileOption.create(:profile_id => @profile.id, :option_id => tar[:option_id])

      # end

    #end

    
    redirect_to  dashboard_user_path(current_user)
    
    
    #scattfold的普通版本

    #if @profile.update(profile_params)

        #redirect_to  dashboard_user_path(current_user)

    #else

        #render edit

    #end

        
  end
  
  private
  def profile_params
    
   
    #可以用的

    params.require(:profile).permit(:location, :gender, profile_option_attributes:[:id, :option_id])
    #可以用的

    
    #params.require(:profile).permit(:location, :gender, :option_ids => [])

    #params.require(:profile).permit(:location, :gender, :option_ids => [], :basic_option_a, :basic_option_b, :basic_option_c, :basic_option_d, :basic_option_e)


  end
  
  def find_user
    @user = current_user
  end
  
  def set_profile
    @profile = @user.profile
  end
  
end

views/dashboard/profiles/new.html.erb
<div class='content_wrapper option_wrapper'> 
    <ul class = 'option_first_banner clearfix'>
        <li class = 'option_right_banner'>
            <%= form_for @profile, :url => dashboard_user_profiles_path, :method => :POST do |f| %>
                <div class="edit_panel panel panel-default">
                    <div class="edit_heading panel-heading">
                        <h3 class="panel-title">個人資料</h3>
                    </div>
                    <div class="panel-body">
                        <div class='option_content'>
                            <div class="form-group">
                                <%= label_tag "地點:" %> <%= f.text_field :location, class:"form-control" %>
                            </div>
                            <div class="form-group">
                                <%= label_tag "性別:" %> <%= f.select :gender, Profile::GENDER_TYPES, class:"form-control" %>
                            </div>
                            <% @issues.each do |issue|%>
                            <div class="form-group">
                                <%= issue.content %>  
                                <%= select_tag "profile[profile_option_attributes][][option_id]", options_from_collection_for_select(issue.option, "id" ,"content"), {:class =>"form-control"} %>
                            </div>
                            <% end %>
                        </div>
                        <div class="form-group">
                            <%= f.submit "送出", class: "btn btn-primary" %>
                        </div>
                    </div>
                </div>
            <% end %>
        </li>
    </ul>
</div>
view/dashboard/respond/special_cates.html.erb
<div class='content_wrapper option_wrapper'> 
<ul class = 'option_first_banner clearfix'>
    <li class = 'option_right_banner'>
        <%= form_for @user, :url => dashboard_user_responds_path, :method => :POST do |f| %>
        
            <div class="edit_panel panel panel-default">
                <div class="edit_heading panel-heading">
                  
                    <h3 class="panel-title">
                      
                    </h3>
                </div>
                <div class="panel-body">
                  <div class='option_content'>
                    <%= f.fields_for @respond do |ff|%>
                    <% @issues.each do |issue|%>
                      <%= label_tag issue.id %>
                      <%= label_tag issue.content %>
                      <%# issue.option.each do |option| %>
                        <div class="form-group">
                          <div class="radio">
                            <%#= f.radio_button :option_id, option.id %><%#= label_tag option.content %>
                            <%#= ff.radio_button :option_id, option.id %><%#= label_tag option.content %>
                            <%= ff.select :option_id, options_from_collection_for_select(issue.option, "id" ,"content"), {:class =>"form-control"} %>
                          </div>   
                        </div>
                      <% end %>    
                    <%# end %>
                    <% end %>
                  </div>
                    <div class="form-group">
                        <%= f.submit "送出", class: "btn btn-primary" %>
                    </div>
                </div>
            </div>
        <% end %>
    </li>
</ul>
</div>


params:

← 回答問題的模式 (後台跟前台) ROR TUTORIAL (3RD ED.) Ch9:Updating, showing, and deleting users →