Activeレコードではないオブジェクト(Hoge)の項目をマルチチェックボックスでUserの子テーブルHogeUserに登録、更新させたい

  • UserクラスとHogeUserクラスは一対多の親子クラスです。
  • HogeオブジェクトはActiveRecordでは無くid,nameといった項目を持っています。
  • Userクラスの保存と共にHogeでチェックが入った項目をHogeUserレコードに複数登録したいです。(チェックが入ってないのは登録されないようにしたいです。)
  • バージョンアップ前のruby1.9.3,rails3.2を使ってます。

まだ中途半端で動いてないですが以下が現在の実装です。

Userクラス

class User < ActiveRecord::Base
  has_many :hoge_users

  attr_accessible ::hoge_users_attributes


  accepts_nested_attributes_for :hoge_users

  validates_associated :hoge_users
  validate :should_have_at_least_one_hoge_user

  def should_have_at_least_one_hoge_user
    errors.add(:hoge_users, 'should have at least one.') if hoge_users.empty?
  end

HogeUserクラス

class HogeUser < ActiveRecord::Base
  belongs_to :hoge
  attr_accessible :hoge, :name, :hoge_id
  validates :hoge_id, :presence => true
end

UsersControllerクラス

class UsersController < ActionController::Base
  def new
    @user = User.new(User::DEFAULT, :as => :admin)  
    respond_to do |format|
      set_objects_for_new_view
      ~

  def create
    @user = User.new(params[:user], :as => :admin)
    hoge_ids = params[:hoge_users_attributes]
    unless hoge_ids == nil
      hoge_ids.each do |hoge_id|
        @user.hoge_users.new(:hoge_id => hoge_id)
      end
    end
    respond_to do |format|
      if @user.save
      ~


   def set_objects_for_new_view
     @hoges = GET::Zone.all
     @hoge_users = @user.hoge_users.new

_form.html.erb

<%= f.fields_for :hoge_users do |hoge_user_f| %>
    <%= render :partial => 'hoge_user_form', :locals => {:f => hoge_user_f} %>
<% end %>

_hoge_user_form.html.erb

<% @hoges.each do |hoge| %>
  <tr>
    <%= hoge.name %>
    <%= check_box_tag 'hoge_users_attributes[]', hoge.id %>
  </tr>
<% end %>
  • ググってみましたがActiveレコード以外から取得する例がありませんでした。HogeをActiveRecordに入れる必要がありますでしょうか?⇒回答で解決。コード修正済み

  • 【追記】上記のようにコード修正すると登録までできるようになりました。ただチェックボックス未選択時のバリデーションが動いてくれません(hoge.idが空)。
    何か間違っている箇所が有ったりしますでしょうか?⇒回答で解決。コード修正済み

【追記2】詳細更新画面について

  • 頂いたご回答で登録処理は動作するようになりました。続いて詳細更新画面が上手く動きません。
  • 詳細でHogeUserに登録されていたものはチェックがついてる状態にしたいです。
  • チェックボックスを外したら削除されるようにしたいです。
  • 新しくチェックを入れたものは追加されるようにしたいです。

UsersControllerクラス

詳細出す前にHogeオブジェクトを取るようにしました。

class UsersController < ActionController::Base
  def show
    @user = target_user
    @hoges = GET::Zone.all

    respond_to do |format|
      format.html { render :partial => 'show' }
      ~
  def update
    @user = target_user

    respond_to do |format|
      if @user.update_attributes(params[:user], :as => :admin)
      ~

_show_user.html.erbビュー

check_boxにhoge_idを指定して登録されていたものはチェックがついてる状態になりました。
"hoge_accounts_attributes"=>{"hoge_id"=>"チェックボックスで選択したhoge.id", "0"=>{"id"=>"登録されたTBL.id"}}}
paramsは↑のものが渡るようになりました。update前にhoge.idを取得してhoge_users.newする形になるのでしょうか?

    <th>ホゲ</th>
    <td>
    <%= f.fields_for :hoge_users do |hoge_user_f| %>
      <% @hoges.each do |hoge| %>
          <%= hoge.name %>
          <%= hoge_user_f.check_box :hoge_id, {:name =>'user[hoge_users_attributes][hoge_id]'}, hoge.id %>
      <% end %>
    <% end %>
    </td>
  </tr>

Userクラス

削除にはallow_destroyオプションつけて_destroyというパラメータを渡さなければいけないとあったのですがチェックを外すと_destroyパラメータが付く形にしたいです。

class User < ActiveRecord::Base
  accepts_nested_attributes_for :hoge_users, :allow_destroy => true