【问题标题】:Create Related Data using Nested attributes使用嵌套属性创建相关数据
【发布时间】:2015-04-22 06:11:30
【问题描述】:

API。现在需要插入一条具有关联记录的记录。我阅读了嵌套属性,但没有任何想法。看不懂。

我在 rails mvc 项目中尝试了一个示例,但即使我也无法在一对一映射本身中创建关联记录。请指导我执行此操作的步骤或任何带有示例的好文章?

无论如何以下是我的工作

我的模特是

class Instructor < ActiveRecord::Base
  has_one :office_assignment
  has_many :departments
  has_and_belongs_to_many :courses

  accepts_nested_attributes_for :office_assignment
end

class OfficeAssignment < ActiveRecord::Base
  belongs_to :instructor
end

用于创建的控制器方法

def new
    @instructor = Instructor.new
  end

  def create
    @instructor = Instructor.new(instructor_params)

    respond_to do |format|
      if @instructor.save

        format.html { redirect_to @instructor, notice: 'Instructor was successfully created.' }
        format.json { render :show, status: :created, location: @instructor }
      else
        format.html { render :new }
        format.json { render json: @instructor.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_instructor
      @instructor = Instructor.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def instructor_params
      params.require(:instructor).permit(:LastName, :FirstMidName, :HireDate, office_assignment_attributes: [:Location])
    end

我的创建表单

<%= form_for @instructor, :html => { :class => "form-horizontal instructor" } do |f| %>

    <% if @instructor.errors.any? %>
    <div id="error_expl" class="panel panel-danger">
      <div class="panel-heading">
        <h3 class="panel-title"><%= pluralize(@instructor.errors.count, "error") %> prohibited this instructor from being saved:</h3>
      </div>
      <div class="panel-body">
        <ul>
        <% @instructor.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
        </ul>
      </div>
    </div>
  <% end %>

  <div class="form-group">
    <%= f.label :LastName, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :LastName, :class => 'form-control' %>
    </div>
    <%= error_span(@instructor[:LastName]) %>
  </div>
  <div class="form-group">
    <%= f.label :FirstMidName, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :FirstMidName, :class => 'form-control' %>
    </div>
    <%= error_span(@instructor[:FirstMidName]) %>
  </div>
  <div class="form-group">
    <%= f.label :HireDate, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :HireDate, :class => 'form-control' %>
    </div>
    <%= error_span(@instructor[:HireDate]) %>
  </div>

    <div class="form-group">
      <%= f.label :Location, :class => 'control-label' %>
      <div class="controls">
        <input type="text" name="office_assignment_Location" class ="form-control">
      </div>
      <%= error_span(@instructor[:HireDate]) %>
    </div>


  <%= f.submit nil, :class => 'btn btn-primary' %>
  <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
            instructors_path, :class => 'btn btn-default' %>

<% end %>

请指导我..

编辑:

html文件的变化

<%= f.fields_for :office_assignment_Location do |loc| %>
    <div class="form-group">
      <%= loc.label :Location, :class => 'control-label' %>
      <div class="controls">
        <%= loc.text_field :Location %>
      </div>
    </div>
    <%= loc.link_to_add "Add Location", :office_assignment_Location , :class=>'btn btn-primary'%>
<% end %>

我在控制器中的参数

def instructor_params
  params.require(:instructor).permit(:LastName, :FirstMidName, :HireDate, office_assignment_attributes: [:id, :Location ,:_destroy])
end

我的架构

create_table "instructors", force: :cascade do |t|
    t.string   "LastName",     limit: 255
    t.string   "FirstMidName", limit: 255
    t.date     "HireDate"
    t.datetime "created_at",               null: false
    t.datetime "updated_at",               null: false
  end

  create_table "office_assignments", primary_key: "Instructor_Id", force: :cascade do |t|
    t.string   "Location",   limit: 255
    t.datetime "created_at",             null: false
    t.datetime "updated_at",             null: false
  end

  add_foreign_key "office_assignments", "instructors", column: "Instructor_Id"

【问题讨论】:

  • 能否请您显示架构以了解更多信息。
  • 您需要在表单中键入嵌套格式,所以请分享架构。
  • @Akhil :我已经发布了答案,请告诉我它是否有效?
  • 朋友们,谢谢,我会检查并告诉你

标签: ruby ruby-on-rails-4 strong-parameters


【解决方案1】:

仅供参考:属性名称应以小写字母开头,而不是大写。

以下是一些变化:

class Instructor < ActiveRecord::Base
  has_one :office_assignment , :dependent => :destroy # add dependent destroy
  has_many :departments
  has_and_belongs_to_many :courses

  accepts_nested_attributes_for :office_assignment,  :reject_if => :all_blank, :allow_destroy => true # add allow destroy
end

强参数的一些变化:

 def instructor_params
      params.require(:instructor).permit(:LastName, :FirstMidName, :HireDate, office_assignment_attributes: [:id, :Lesson ,:_destroy])
    end

注意:不要忘记在office_assignment_attributes中添加:id:_destroy

现在在视图中(form_template):

而不是这个:

<div class="form-group">
      <%= f.label :Location, :class => 'control-label' %>
      <div class="controls">
        <input type="text" name="office_assignment_Location" class ="form-control">
      </div>
      <%= error_span(@instructor[:HireDate]) %>
    </div>

应该是:

<%= nested_form_for @instructor, :html => { :class => "form-horizontal instructor" } do |f| %>

......
.....

<%= f.fields_for :office_assignment do |loc| %>
      <div class="form-group">
       <%= loc.label :Location, :class => 'control-label' %>
        <div class="controls"> 
          <%= loc.text_field :Location %>
        </div>
      </div>
    <% end %>
     <%= f.link_to_add "Add Location", :office_assignment , :class=>'btn btn-primary'%>

您必须像这样创建嵌套表单。希望对您有所帮助。

注意:在您的表单中使用nested_form_for 而不是form_for: 供您参考:

【讨论】:

  • 嗨,我想我需要研究更多。我根据您的建议进行了更改,但现在创建页面时出现 'ActionView::Template::Error (undefined method `link_to_add' for #<:helpers::formbuilder:0x007f7d3c00b4a8>) 错误:' .但我在应用程序助手中添加了助手
  • @Akhil :无需在应用程序帮助文件中添加任何帮助方法。安装 gem "nested_form" 并在 application.js 文件中添加 //= require jquery_nested_form
  • @Akhil :我已经用:reject_if =&gt; :all_blank 更新了模型的答案并重新启动服务器然后尝试
  • 谢谢,现在它显示错误为无效关联。确保accepts_nested_attributes_for 用于:office_assignment_Location 关联 所以与属性相关的东西
  • :office_assignment替换:office_assignment_Location
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多