Ruby on rails Rails表单是否通过与其他属性的关联来实现?

Ruby on rails Rails表单是否通过与其他属性的关联来实现?,ruby-on-rails,ruby,nested-forms,has-many-through,simple-form,Ruby On Rails,Ruby,Nested Forms,Has Many Through,Simple Form,如何通过具有附加属性的关联为具有多个:的生成表单字段 有很多:通过关系还有一个名为weight的附加列 以下是联接表的迁移文件: create_table :users_widgets do |t| t.integer :user_id t.integer :widget_id t.integer :weight t.timestamps end 模型如下所示: User has_many :widgets, :through => :users_widgets,

如何通过具有附加属性的关联为具有多个:的
生成表单字段

有很多:通过
关系还有一个名为
weight
的附加列

以下是联接表的迁移文件:

create_table :users_widgets do |t|
  t.integer :user_id
  t.integer :widget_id
  t.integer :weight

  t.timestamps
end
模型如下所示:

User
  has_many :widgets, :through => :users_widgets,
           :class_name => 'Widget',
           :source => :widget
  has_many :users_widgets
  accepts_nested_attributes_for :widgets # not sure if this is necessary


Widget
  has_many :users, :through => :users_widgets,
           :class_name => 'User',
           :source => :user
  has_many :users_widgets
  accepts_nested_attributes_for :users # not sure if this is necessary


UsersWidget
  belongs_to :user
  belongs_to :widget
为了简单起见,Widget和User只有一个自己的字段,称为
name
,因此
User.first.name
Widget.first.name

问题:

  • 如何将具有相应权重的小部件下拉选择附加到用户创建/编辑表单

  • 如何向用户动态添加其他小部件表单,或向小部件动态添加用户表单,以便轻松添加或删除这些关系?用于
gem的
nested\u form\u似乎是一个完美的解决方案,但我一直无法让它正常工作

  • 除了模型和表单部分,是否需要对控制器进行任何更改


  • 速记。。我对在用户表单中创建新的小部件或在小部件表单中创建新用户不感兴趣,我只希望能够从现有对象中进行选择


    我正在运行Rails 3.1和simple_form 2.0.0dev来生成我的表单。

    根据您的问题。我做了一个简单的应用程序。 资料来源如下: 我将其部署到heroku,您可以打开页面:

    答复

  • 您希望用户表单可以选择具有权重的小部件,需要做更多的工作。下拉选择无法满足您的要求

  • 我在一个“bootstrap rails”插件中混合了“nested_form”,您可以更轻松地添加嵌套的_字段

  • 在我的示例中,需要添加一个操作调用select,并使WidgetsController#create可以用:js响应


  • 代码基于简单表单,您可以尝试一下。

    我将使用我创建的用于处理动态嵌套表单的gem解决您的问题。我还必须举例说明不同类型的关系

    你的不包括字面上,但不是很难从中得出。在您的模型中,您应该写:

    class User 
      has_many :users_widgets
      has_many :widgets, :through -> :user_widgets
    
      accepts_nested_attributes_for :user_widgets, :reject_if => :all_blank, :allow_destroy => true
    
      #...
    end
    
    然后,您需要创建一个局部视图,该视图将列出链接的
    用户小部件
    。将此部分放在名为
    users/\u user\u widget\u fields.html.haml
    的文件中:

    .nested-fields
      = f.association :widget, :collection => Widget.all, :prompt => 'Choose an existing widget'
      = f.input :weight, :hint => 'The weight will determine the order of the widgets'
      = link_to_remove_association "remove tag", f
    
    users/edit.html.haml
    中,您可以编写:

    = simple_form_for @user do |f|
      = f.input :name
    
      = f.simple_fields_for :user_widgets do |user_widget|
        = render 'user_widget_fields', :f => user_widget
      .links
        = link_to_add_association 'add widget', f, :user_widgets
    

    希望这有帮助。

    非常感谢nathanvda提供的cocoon指针。在rails 4.0.0-rc1下尝试实现此功能时遇到的一些问题让我挠头,我想我会分享我的发现,以防有人在尝试此udner rails 4时遇到同样的问题

    以上面的代码为例,我将user_id和widget_id添加到允许的参数中,因为它们保存在连接表user_widgets中。在rails 3中,您必须将它们添加到用户模型中的attr_accessible中,但在rails 4中,您必须将它们添加到用于嵌套的主模型控制器中允许的参数中,因此这里将是users_控制器:

    params.require(:user).permit(...user_fields...,  
      user_widgets_attributes: [:user_id, :widget_id])
    
    仅此一步,您最终会遇到以下几个问题:

  • 更新用户记录时,每个关联(小部件)都会成倍增加。更新和保存记录时,1变为2、4、8等
  • 删除关联无效,该字段将从表单中删除,但关联仍保留在数据库中
  • 要解决这些问题,还需要将:id和:\u destroy添加到允许的属性列表中:

    params.require(:user).permit(...user_fields...,  
      user_widgets_attributes: [:user_id, :widget_id, :id, :_destroy])
    
    在那之后,它的工作完美无瑕

    尤尔根


    PS:现在,在发布与rails 4兼容的gem之前,您必须使用gem文件中的git存储库来使用rails 4下的cocoon。感谢nathanvda关于我的bug报告的电子邮件

    谢谢@nathanvda,这正是我想要的。你的宝石让这变得特别容易。附言:在我给你奖金之前,奖金就自动分配了,但我已经ping了mods寻求帮助。如果设置了几乎完全相同的模型,这非常有用。我发现像这样的复杂形式让人心烦意乱,谢谢你的精彩回答!我知道这不是一个很好的评论表,但我只是想说声谢谢。我花了大约6个小时试图弄明白如何应用cocoon加入表,几乎准备放弃。