【问题标题】:Cannot access associated model attributes within a form无法访问表单中的关联模型属性
【发布时间】:2015-05-17 19:41:05
【问题描述】:

我正在尝试为 has_many :through 关系构建一个表单。问题是,我可以从表单中的连接表(:通过)访问属性,但不能访问其他表。

我的模型如下所示:

class Recipe < ActiveRecord::Base
   has_many :quantities
   has_many :ingredients, through: :quantities
   accepts_nested_attributes_for :quantities
end

class Quantity < ActiveRecord::Base
  belongs_to :recipe
  belongs_to :ingredient
end

class Ingredient < ActiveRecord::Base
  has_many :quantities
  has_many :recipes, through: :quantities 
end

我的表格:

<%= form_for(@recipe) do |f| %>
  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>


  <div class="quantities">
    <%= f.fields_for :quantities do |builder| %>
      <%= render 'quantity_fields', :f => builder%>
    <% end %>
    <%= link_to_add_association 'Add', f, :quantities %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

以及数量字段部分:

<p>
<%= f.label :value, "Value" %>
<%= f.text_field :value %>
<%= f.label :unit, "Unit" %>
<%= f.text_field :unit %>
<%= f.text_field :ingredient %>
<%= f.fields_for :ingredient do |builder|%>
  <%= builder.label :name, "Ingredient"%>
  <%= builder.text_field :name %>
<% end %>
</p>

数量属性的字段是正确的,但成分名称的文本字段(在数量字段部分内)保持为空。 另一方面,在 Rails 控制台上,我可以轻松地在数量对象上使用成分方法并获得结果。

我一直在尝试找到解决这个问题的方法,这让我非常沮丧。我确信这是一项标准任务,我只是遗漏了一小部分。谁能帮帮我?

编辑:

另外,当我将配方表更改为直接渲染成分时,它不起作用。文本字段保持为空。

<%= form_for(@recipe) do |f| %>
  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>

  <div class="ingredients">
    <%= f.fields_for :ingredients do |builder| %>
      <p>
      <%= builder.label :name, "Name" %>
      <%= builder.text_field :name %>
      <%= builder.label :description, "Description" %>
      <%= builder.text_field :description %>
      </p>
    <% end %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

编辑 2: 配方控制器:

class RecipesController < ApplicationController
  before_action :set_recipe, only: [:show, :edit, :update, :destroy]

  # GET /recipes
  # GET /recipes.json
  def index
    @recipes = Recipe.all
  end

  # GET /recipes/1
  # GET /recipes/1.json
  def show
  end

  # GET /recipes/new
  def new
    @recipe = Recipe.new
  end

  # GET /recipes/1/edit
  def edit
  end

  # POST /recipes
  # POST /recipes.json
  def create
    @recipe = Recipe.new(recipe_params)

    respond_to do |format|
      if @recipe.save
        format.html { redirect_to @recipe, notice: 'Recipe was successfully created.' }
        format.json { render :show, status: :created, location: @recipe }
      else
        format.html { render :new }
        format.json { render json: @recipe.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /recipes/1
  # PATCH/PUT /recipes/1.json
  def update
    respond_to do |format|
      if @recipe.update(recipe_params)
        format.html { redirect_to @recipe, notice: 'Recipe was successfully updated.' }
        format.json { render :show, status: :ok, location: @recipe }
      else
        format.html { render :edit }
        format.json { render json: @recipe.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /recipes/1
  # DELETE /recipes/1.json
  def destroy
    @recipe.destroy
    respond_to do |format|
      format.html { redirect_to recipes_url, notice: 'Recipe was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def recipe_params
      params.require(:recipe).permit(:title, :description, quantities_attributes: [:value, :unit, :recipe, :ingredient, :_destroy])
    end
end

【问题讨论】:

  • 请同时发布您的控制器代码。

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


【解决方案1】:

当以这种方式使用has_many :through 关联时,您可以像这样设置模型:

class Recipe < ActiveRecord::Base
   has_many :quantities
   has_many :ingredients, inverse_of: :recipes

   accepts_nested_attributes_for :quantities
end

class Quantity < ActiveRecord::Base
  belongs_to :recipe
  belongs_to :ingredient

  accepts_nested_attributes_for :ingredients
end

class Ingredient < ActiveRecord::Base
  has_many :quantities
  has_many :recipes, inverse_of: :ingredients 
end

This article 在类似的上下文中使用 has_many :through 关联覆盖嵌套属性。希望这会有所帮助!

【讨论】:

  • 感谢您的回答,但这并不能解决我的问题。据我了解,这只是建立了一个空的成分,所以会有一些东西可以展示。但我已经有相关的成分,只是无法从视图中访问它们。
  • 你是对的,我在第一次阅读时肯定误解了这个问题。我又看了一遍,改写了答案。让我知道它是否有效。
  • 再次感谢。我现在终于可以解决了。数量模型中的accepts_nested_attributes_for :ingredients 行是关键。我没想到会这样,因为我不想通过数量来编辑成分,但是没关系。还学到了一些关于 inverse_of 的新知识。谢谢! :)
  • 太棒了! :D 很高兴能帮上忙!
猜你喜欢
  • 2016-10-09
  • 1970-01-01
  • 2014-04-27
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
  • 2017-05-04
相关资源
最近更新 更多