has_many:through和fields_for的问题

时间:2009-12-03 13:40:08

标签: ruby-on-rails ruby activerecord forms has-many-through

我有一个很基本的联想:

# user.rb
class User < ActiveRecord::Base
  has_many :services, :through => :subscriptions
  has_many :subscriptions, :accessible => true
  accepts_nested_attributes_for :subscriptions
end

# service.rb
class Service < ActiveRecord::Base
  has_many :users, :through => :subscriptions
  has_many :subscriptions
end

# subscription.rb
class Subscription < ActiveRecord::Base
  belongs_to :user
  belongs_to :service
end

订阅还有一个布尔列“通知”,我需要单独配置,所以我查看API,按照示例并为我的表单提供了此代码:

- if current_user.subscriptions.length > 0
  %fieldset#subscriptions
    %legend Abonnements
    %table
      %tr
        %th.name
        %th.notification Notifications?
      - for subscription in current_user.subscriptions do
        %tr
          - f.fields_for :subscriptions, subscription do |s|
            %td=subscription.service.name
            %td= s.check_box :notification

但是当我保存表格时,所有相关的订阅都会被销毁。然而,当我选中复选框时,它不会被删除,但复选框不会保存。有谁知道我做错了什么?

2 个答案:

答案 0 :(得分:2)

尝试了近2个小时后,我终于开始工作了。对代码稍作修改就足够了:

# _form.html.haml
# […]
- if current_user.subscriptions.length > 0
  %fieldset#subscriptions
    %legend Abonnements
    %table
      %tr
        %th.name
        %th.notification Notifications?
      - f.fields_for :subscriptions do |sub|
        %tr
          %td= sub.object.service.name
          %td 
            = sub.check_box :notification
            = hidden_field_tag "user[service_ids][]", sub.object.service.id
# […]

由于params[:user][:service_ids]为空,因此删除了整个关联。

答案 1 :(得分:0)

您没有向表单提交任何订阅。如果不单击该复选框,则无法为该订阅提交任何内容,因此嵌套属性功能将清除订阅。尝试使用订阅的服务ID放入隐藏字段。

我相信你也错误地设置了嵌套属性的表单。试试这个:

- if current_user.subscriptions.length > 0
  %fieldset#subscriptions
    %legend Abonnements
    %table
      %tr
        %th.name
        %th.notification Notifications?
      - f.fields_for :subscriptions do |sub|
        %tr
          %td= sub.object.service.name
          %td 
            = sub.check_box :notification
            = sub.hidden_field :service_id