ruby-on-rails – 在预构建嵌套模型实例时,Rails nested_form link_to_add无法正常工作

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 在预构建嵌套模型实例时,Rails nested_form link_to_add无法正常工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在粗略地将ryanb的令人敬畏的nested_form gem集成到我的rails 3.1.3应用程序中.我担心我的 Javascript技能太有限了,不知道这是我的代码(可能)还是需要改变的宝石.也许有人可以提供帮助.

设置:我有一个“:household”类:accepts_nested_attributes_for“:members(people)”.我正在运行开发服务器.我将nested_form.js移动到/ app / assets / javascripts目录.我几乎肯定它只被采购一次.

问题:如果在家庭控制器“新”方法中,我这样做:

  1. @household = Household.new

我只看到视图中的家庭原生字段(预期),并且“link_to_remove”和“link_to_add”链接呈现/删除成员字段部分(预期).但是,如果我这样做:

  1. @household = Household.new
  2. @household.members.build

我在视图中看到了家庭原生字段(预期),成员本地字段的一个呈现部分(预期),但“link_to_remove”和“link_to_add”什么都不做(意外).我不能添加另一个:成员部分在那一点,也不删除已经显示的:成员部分.

我很难过.以下是看似相关的精简源文件.我从git存储库获取了nested_form插件(最后捆绑了2012.04.18)…

/app/models/household.rb

  1. class Household < ActiveRecord::Base
  2. has_many :members,:class_name => "Person"
  3. accepts_nested_attributes_for :members
  4. attr_accessible :id,:name,:member_ids
  5. attr_accessible :members_attributes
  6. end #class

/app/models/person.rb

  1. class Person < ActiveRecord::Base
  2. belongs_to :household
  3. attr_accessible :id,:name_given,:name_middle,:name_family,:household_id
  4. end #class

/app/controllers/households_controller.rb

  1. <snip>
  2. # GET /households/new
  3. # GET /households/new.json
  4. def new
  5. @household = Household.new
  6. @household.members.build # <---- Removing this changes the behavior
  7.  
  8. respond_to do |format|
  9. format.html # new.html.erb
  10. format.json { render json: @household }
  11. end
  12. end

/app/views/households/new.html.haml

  1. .headbg
  2. .pad
  3. %h2 Enter a New Household
  4. = render 'form'

/app/views/households/_form.html.haml

  1. = nested_form_for @household,:html => { :class => "form-horizontal"} do |f|
  2.  
  3. %fieldset
  4. %legend Household
  5.  
  6. .control-group
  7. = f.label( :name,{ :class => 'control-label'} )
  8. .controls
  9. = f.text_field( :name,{ :class => 'span5',:placeholder => '[household name]'} )
  10.  
  11. %fieldset
  12. %legend Household Members
  13. = f.fields_for :members,:html => { :class => "form-inline"} do |nested_f|
  14. = render :partial => 'people/nested_person_form',:locals => { :f => nested_f }
  15. = yield :nested_person_form
  16. %p
  17. = f.link_to_add "New Household Member",:members
  18.  
  19. .form-actions
  20. = button_tag( :class => "btn btn-primary",:disable_with => "Saving..." ) do
  21. %i.icon-ok.icon-white
  22. Save
  23. = link_to households_path do
  24. .btn.btn-info
  25. %i.icon-arrow-left.icon-white
  26. Back to Households

/app/views/people/_nested_person_form.html.haml

  1. - content_for :nested_person_form do
  2.  
  3. .nested-fields
  4. .row
  5. .span8
  6. .control-group
  7. = f.label( "Name",{ :class => 'control-label'} )
  8. .controls
  9. = f.text_field( :name_given,{ :class => 'span2',:placeholder => '[first]'} )
  10. = f.text_field( :name_middle,:placeholder => '[middle]'} )
  11. = f.text_field( :name_family,:placeholder => '[last]'} )
  12. .span1
  13. = f.link_to_remove "Remove"

/app/assets/javascripts/nested_form/nested_form.js

  1. jQuery(function($) {
  2. window.NestedFormEvents = function() {
  3. this.addFields = $.proxy(this.addFields,this);
  4. this.removeFields = $.proxy(this.removeFields,this);
  5. };
  6.  
  7. NestedFormEvents.prototype = {
  8. addFields: function(e) {
  9. // Setup
  10. var link = e.currentTarget;
  11. var assoc = $(link).attr('data-association'); // Name of child
  12. var content = $('#' + assoc + '_fields_blueprint').html(); // Fields template
  13.  
  14. // Make the context correct by replacing new_<parents> with the generated ID
  15. // of each of the parent objects
  16. var context = ($(link).closest('.fields').find('input:first').attr('name') || '').replace(new RegExp('\[[a-z]+\]$'),'');
  17.  
  18. // context will be something like this for a brand new form:
  19. // project[tasks_attributes][new_1255929127459][assignments_attributes][new_1255929128105]
  20. // or for an edit form:
  21. // project[tasks_attributes][0][assignments_attributes][1]
  22. if (context) {
  23. var parentNames = context.match(/[a-z_]+_attributes/g) || [];
  24. var parentIds = context.match(/(new_)?[0-9]+/g) || [];
  25.  
  26. for(var i = 0; i < parentNames.length; i++) {
  27. if(parentIds[i]) {
  28. content = content.replace(
  29. new RegExp('(_' + parentNames[i] + ')_.+?_','g'),'$1_' + parentIds[i] + '_');
  30.  
  31. content = content.replace(
  32. new RegExp('(\\[' + parentNames[i] + '\\])\\[.+?\\]','$1[' + parentIds[i] + ']');
  33. }
  34. }
  35. }
  36.  
  37. // Make a unique ID for the new child
  38. var regexp = new RegExp('new_' + assoc,'g');
  39. var new_id = new Date().getTime();
  40. content = content.replace(regexp,"new_" + new_id);
  41.  
  42. var field = this.insertFields(content,assoc,link);
  43. $(link).closest("form")
  44. .trigger({ type: 'nested:fieldAdded',field: field })
  45. .trigger({ type: 'nested:fieldAdded:' + assoc,field: field });
  46. return false;
  47. },insertFields: function(content,link) {
  48. return $(content).insertBefore(link);
  49. },removeFields: function(e) {
  50. var link = e.currentTarget;
  51. var hiddenField = $(link).prev('input[type=hidden]');
  52. hiddenField.val('1');
  53. // if (hiddenField) {
  54. // $(link).v
  55. // hiddenField.value = '1';
  56. // }
  57. var field = $(link).closest('.fields');
  58. field.hide();
  59. $(link).closest("form").trigger({ type: 'nested:fieldRemoved',field: field });
  60. return false;
  61. }
  62. };
  63.  
  64. window.nestedFormEvents = new NestedFormEvents();
  65. $('form a.add_nested_fields').live('click',nestedFormEvents.addFields);
  66. $('form a.remove_nested_fields').live('click',nestedFormEvents.removeFields);
  67. });

解决方法

我只是遇到了同样的问题,并通过以下方式修复它:

确保你头脑中有一个最新的jQuery.js文件.加载后,请不要使用从gem安装的nested_form.js文件.而是使用jquery_nested_form.js.

只要在jquery_nested_form文件之前有jquery链接,这个解决方案就可以正常工作:

  1. <%= javascript_include_tag :defaults,'jquery_nested_form' %>

以下是jquery_nested_form.js文件代码

  1. jQuery(function($) {
  2. window.NestedFormEvents = function() {
  3. this.addFields = $.proxy(this.addFields,this);
  4. };
  5.  
  6. NestedFormEvents.prototype = {
  7. addFields: function(e) {
  8. // Setup
  9. var link = e.currentTarget;
  10. var assoc = $(link).attr('data-association'); // Name of child
  11. var content = $('#' + assoc + '_fields_blueprint').html(); // Fields template
  12.  
  13. // Make the context correct by replacing new_<parents> with the generated ID
  14. // of each of the parent objects
  15. var context = ($(link).closest('.fields').closestChild('input,textarea').eq(0).attr('name') || '').replace(new RegExp('\[[a-z]+\]$'),link);
  16. // bubble up event upto document (through form)
  17. field
  18. .trigger({ type: 'nested:fieldAdded',removeFields: function(e) {
  19. var $link = $(e.currentTarget),assoc = $link.data('association'); // Name of child to be removed
  20.  
  21. var hiddenField = $link.prev('input[type=hidden]');
  22. hiddenField.val('1');
  23.  
  24. var field = $link.closest('.fields');
  25. field.hide();
  26.  
  27. field
  28. .trigger({ type: 'nested:fieldRemoved',field: field })
  29. .trigger({ type: 'nested:fieldRemoved:' + assoc,nestedFormEvents.removeFields);
  30. });
  31. // http://plugins.jquery.com/project/closestChild
  32. /*
  33. * Copyright 2011,Tobias Lindig
  34. *
  35. * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.PHP)
  36. * and GPL (http://www.opensource.org/licenses/gpl-license.PHP) licenses.
  37. *
  38. */
  39. (function($) {
  40. $.fn.closestChild = function(selector) {
  41. // breadth first search for the first matched node
  42. if (selector && selector != '') {
  43. var queue = [];
  44. queue.push(this);
  45. while(queue.length > 0) {
  46. var node = queue.shift();
  47. var children = node.children();
  48. for(var i = 0; i < children.length; ++i) {
  49. var child = $(children[i]);
  50. if (child.is(selector)) {
  51. return child; //well,we found one
  52. }
  53. queue.push(child);
  54. }
  55. }
  56. }
  57. return $();//nothing found
  58. };
  59. })(jQuery);

希望这可以帮助!

猜你在找的Ruby相关文章