Rails 4和Mongoid嵌套的has_one关系不起作用?

时间:2016-04-14 11:54:33

标签: ruby-on-rails ruby mongodb ruby-on-rails-4 mongoid

我在嵌入式关系中遇到has_one关系问题。这种关系是食谱embeds_many ilist,ilist has_one成分。我正在使用单一表格,但是当我提交时,该成分不会存储在ilist中。

食谱模型

class Recipe
 include Mongoid::Document
 .
 .
   embeds_many :ilists
    accepts_nested_attributes_for :ilists,
    :allow_destroy => true,
    :reject_if     => :all_blank,
    autosave: true
end

食谱控制器

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
     3.times { @recipe.ilists.build }
  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, :photo, :type, :preptime, :serves, :description, :calories, :protien, :Fat, :cholesterol, :sodium, :potassium, :carbohydrate, :fiber, :sugar, :calcium, :iron, :zinc, :copper, :choline, :fluoride, :folate, :magnesium, :manganese, :phosphorus, :potassium, :selenium, :vitaminA, :vitaminB1, :vitaminB2, :vitaminB3, :vitaminB4, :vitaminB5, :vitaminB6, :vitaminB12, :vitaminC, :vitaminD, :vitaminE, :vitaminK, :vegetarian, :lactovegetarian, :vegan, :halal, :pescetarian, :glutenfree, :alcohol, ilists_attributes: [ :ingrediant, :quantity])
    end
end

ilist模型

class Ilist
  include Mongoid::Document
  field :quantity, type: Integer

  has_one :ingrediant
    accepts_nested_attributes_for :ingrediant,
    :allow_destroy => true,
    :reject_if     => :all_blank,
    autosave: true
  embedded_in :recipe, inverse_of: :ilists
end
**ilist controller params**
params.require(:ilist).permit( ingrediant_attribute: [ :name, :calories,..], :quantity)

成分模型(我知道我拼错了成分)

class Ingrediant
 include Mongoid::Document
 field :name, type: String
 field :calories, type: BigDecimal
 field :protien, type: BigDecimal
 .
 .

 belongs_to :ilist
end

形式:

<%= form_for @recipe, :html => { :multipart => true } do |f| %>
.
<%= f.fields_for :ilists do |builder| %>
  <tr>

  <td><%= builder.collection_select :ingrediant, Ingrediant.all, :id, :name, {} %></td>
  <td><%= builder.text_field :quantity %></td>

  </tr>
<% end %>

在控制台的HTTP帖子中,我可以看到配方帖子和

"..,ilists_attributes"=>{"0"=>{"ingrediant"=>"56ccc8b7de301b1904488361", "quantity"=>"100"},..

56ccc8b7de301b1904488361是成分数据库中鸡胸肉的_id,我不想只需要_id我需要能够查询整个成分。

这个想法是每个ilist包含来自成分的所有信息以及数量,所以我可以通过控制器在创建时计算配方的营养价值(不知道如何做到这一点,但一次只有一个问题)

1 个答案:

答案 0 :(得分:0)

你已经在一个配方中嵌入了一个ilist,但是你还没有嵌入ilist的配料,因此你有两个文件集,食谱&amp;通过嵌入式ilists相关的成分。要获得ingrediant,您需要调用recipe.ilist.ingrediant来返回文档。因为它是一个单独但相关的文件mongoid只会将_id存储在ilist中。

作为旁注,如果您有机会,我会建议您出于维护原因更新收藏品的拼写。