无法在Rails中存储模型的嵌套属性值(Rails配方36) [英] Failing to store nested attributes values for models in rails (rails recipes 36)

查看:68
本文介绍了无法在Rails中存储模型的嵌套属性值(Rails配方36)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试存储我添加的每个级别的值,当我使用添加/删除按钮时,可见字段的数量将按照其应有的方式进行更新,但是当我按下提交"时,只会存储游戏名称.分数以某种方式被丢弃.

I am trying to store the value for each level i add, the number of fields visible gets updated as they should when i use add/remove buttons, but when i press submit only the game name gets stored. The scores are discarded somehow.

<h1>Editing game</h1>

<% flash.each do |name, msg| -%>
    <%= content_tag :div, msg, class: name %>
<% end -%>


<!--START-->
<%= form_for @game do |f| %>
    <%= f.label :name %> <%= f.text_field :name %>
    <h3>Scores:</h3>

    <%= f.fields_for(:levels) do |level_form| %>
        <!--<%= level_form.label :score %>-->
        <%= level_form.text_field :score %>
        </br>
    <% end %>

    <%= f.submit %>
<% end %>
           <!--END-->

<%= button_to "Add Level",
              :action => 'add_level',
              :id =>@game
              %>
<%= button_to "Remove Level",
              :action => 'remove_level',
              :id =>@game
%>

<%= link_to 'Show', @game %> |
<%= link_to 'Back', games_path %>

我的游戏模型:

class Game < ActiveRecord::Base
    belongs_to :user
    has_many :levels
    accepts_nested_attributes_for :levels

end

我的关卡模型:

class Level < ActiveRecord::Base
  belongs_to :game
end

我的游戏控制器:

class GamesController < ApplicationController
  before_action :set_game,:initialize, only: [:show, :edit, :update, :destroy]



  attr_reader :levels


  def initialize
    if @game
      @levels = [] unless @levels
      get_levels
    end

  end


  def add_level
    set_game
    @level = @game.levels.create(:game_id=>params[:id])
    @level.save
    flash[:notice]="Level added"

    redirect_to edit_game_path(params[:id])

  end

  def remove_level
      set_game
      unless @game.levels.length < 2
        get_levels
        @level=@levels.pop
        @level.destroy
        flash[:notice]="Removed Level"
      else
        flash[:notice]="Cannot remove last Level"

      end
      redirect_to edit_game_path(params[:id])


  end

  def save_scores
    #Save all scores from fields in editview


     redirect_to edit_game_path(params[:id])

  end

  # GET /games
  # GET /games.json
  def index
    @games = Game.where(:user_id=> current_user.id)
  end

  # GET /games/1
  # GET /games/1.json
  def show
    get_levels
    respond_to do |format|
        format.html { redirect_to games_url(params[:id]) }
        format.json { render json: @levels}
    end

  end

  # GET /games/new
  def new
    @game = Game.new
    @game.user_id = current_user.id
    @game.save
    @level = @game.levels.create(:game_id=>@game)
    @level.save
  end


  # GET /games/1/edit
  def edit

  end

  # POST /games
  # POST /games.json
  def create
    @game = Game.new(game_params)

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

  # PATCH/PUT /games/1
  # PATCH/PUT /games/1.json
  def update
    respond_to do |format|
      if @game.update(game_params)
        format.html { redirect_to @game, notice: 'Game was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @game.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /games/1
  # DELETE /games/1.json
  def destroy
    @game.destroy
    respond_to do |format|
      format.html { redirect_to games_url }
      format.json { head :no_content }
    end
  end

  private
  #levels for game
  def get_levels
    @levels =  Level.where(:game_id=>@game)
  end

    # Use callbacks to share common setup or constraints between actions.
    def set_game
        @game = Game.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def game_params
      params.require(:game).permit(:List)
    end
end

Development.log:

Development.log:

Started POST "/games/add_level?id=18" for 127.0.0.1 at 2013-08-12 14:06:02 +0200
Processing by GamesController#add_level as HTML
  Parameters: {"authenticity_token"=>"tlSgBCHlMjEbSeM8NDRDkkR/cme8yHhvfb3///rzYos=", "id"=>"18"}
  Game Load (0.1ms)  SELECT "games".* FROM "games" WHERE "games"."id" = ? LIMIT 1  [["id", "18"]]
   (0.1ms)  begin transaction
  SQL (0.6ms)  INSERT INTO "levels" ("created_at", "game_id", "updated_at") VALUES (?, ?, ?)  [["created_at", Mon, 12 Aug 2013 12:06:02 UTC +00:00], ["game_id", 18], ["updated_at", Mon, 12 Aug 2013 12:06:02 UTC +00:00]]
   (2.6ms)  commit transaction
   (0.1ms)  begin transaction
   (0.0ms)  commit transaction
Redirected to http://127.0.0.1:3000/games/18/edit
Completed 302 Found in 8ms (ActiveRecord: 3.6ms)


Started GET "/games/18/edit" for 127.0.0.1 at 2013-08-12 14:06:02 +0200
Processing by GamesController#edit as HTML
  Parameters: {"id"=>"18"}
  Game Load (0.2ms)  SELECT "games".* FROM "games" WHERE "games"."id" = ? LIMIT 1  [["id", "18"]]
  Level Load (0.2ms)  SELECT "levels".* FROM "levels" WHERE "levels"."game_id" = ?  [["game_id", 18]]
  Rendered games/edit.html.erb (11.2ms)
Completed 200 OK in 16ms (Views: 12.7ms | ActiveRecord: 0.8ms)


Started PATCH "/games/18" for 127.0.0.1 at 2013-08-12 14:06:07 +0200
Processing by GamesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"tlSgBCHlMjEbSeM8NDRDkkR/cme8yHhvfb3///rzYos=", "game"=>{"name"=>"ll", "levels_attributes"=>{"0"=>{"score"=>"10", "id"=>"95"}, "1"=>{"score"=>"20", "id"=>"96"}, "2"=>{"score"=>"30", "id"=>"97"}}}, "commit"=>"Update Game", "id"=>"18"}
  Game Load (0.1ms)  SELECT "games".* FROM "games" WHERE "games"."id" = ? LIMIT 1  [["id", "18"]]
Unpermitted parameters: name, levels_attributes
   (0.1ms)  begin transaction
   (0.1ms)  commit transaction
Redirected to http://127.0.0.1:3000/games/18
Completed 302 Found in 4ms (ActiveRecord: 0.5ms)


Started GET "/games/18" for 127.0.0.1 at 2013-08-12 14:06:07 +0200
Processing by GamesController#show as HTML
  Parameters: {"id"=>"18"}
  Game Load (0.2ms)  SELECT "games".* FROM "games" WHERE "games"."id" = ? LIMIT 1  [["id", "18"]]
Redirected to http://127.0.0.1:3000/games.18
Completed 302 Found in 3ms (ActiveRecord: 0.4ms)


Started GET "/games.18" for 127.0.0.1 at 2013-08-12 14:06:07 +0200
Processing by GamesController#index as 
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
  Game Load (0.2ms)  SELECT "games".* FROM "games" WHERE "games"."user_id" = 1
DEPRECATION WARNING: :confirm option is deprecated and will be removed from Rails 4.1. Use 'data: { confirm: 'Text' }' instead. (called from block in _app_views_games_index_html_erb__4567347473113639552_70262937037440 at /Users/david/Repositories/domain_devise/devise_example-master/app/views/games/index.html.erb:27)
  Rendered games/index.html.erb (2.1ms)
Completed 200 OK in 9ms (Views: 5.8ms | ActiveRecord: 0.7ms)
[2013-08-12 14:06:07] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true


Started GET "/games/18/edit" for 127.0.0.1 at 2013-08-12 14:06:15 +0200
Processing by GamesController#edit as HTML
  Parameters: {"id"=>"18"}
  Game Load (0.1ms)  SELECT "games".* FROM "games" WHERE "games"."id" = ? LIMIT 1  [["id", "18"]]
  Level Load (0.1ms)  SELECT "levels".* FROM "levels" WHERE "levels"."game_id" = ?  [["game_id", 18]]
  Rendered games/edit.html.erb (6.5ms)
Completed 200 OK in 10ms (Views: 7.3ms | ActiveRecord: 0.5ms)

更改为允许:name和:levels_attributes后,我仍然得到:

After changing to permit :name and :levels_attributes I still get:

Started PATCH "/games/21" for 127.0.0.1 at 2013-08-12 14:36:07 +0200
Processing by GamesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"tlSgBCHlMjEbSeM8NDRDkkR/cme8yHhvfb3///rzYos=", "game"=>{"name"=>"30", "levels_attributes"=>{"0"=>{"score"=>"40", "id"=>"100"}}}, "commit"=>"Update Game", "id"=>"21"}
  Game Load (0.2ms)  SELECT "games".* FROM "games" WHERE "games"."id" = ? LIMIT 1  [["id", "21"]]
Unpermitted parameters: levels_attributes
   (0.1ms)  begin transaction
   (0.1ms)  commit transaction
Redirected to http://127.0.0.1:3000/games/21
Completed 302 Found in 27ms (ActiveRecord: 1.8ms)

推荐答案

请将game_params方法更改为以下方法.

Please change the game_params method to below.

我不确定您允许的:List参数.

I'm not sure of the :List parameters you are allowing.

def game_params
  params.require(:game).permit(:name, levels_attributes: [:score, :id])
end

我希望这会有所帮助.

这篇关于无法在Rails中存储模型的嵌套属性值(Rails配方36)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆