即使指定了Rails,也不包括SQL Query中的属性

时间:2017-12-18 12:32:05

标签: ruby-on-rails

尽管提供了名称,但SQL查询清楚地表明它没有正确传递。就我所知,Rails控制台并不需要任何白名单参数,但我也包含了我的控制器。

在rails控制台中查询:Profession.first.skills.create(name: 'rails')

  Profession Load (0.5ms)  SELECT  "professions".* FROM "professions" ORDER BY "professions"."id" ASC LIMIT $1  [["LIMIT", 1]]
   (0.2ms)  BEGIN
  Skill Exists (0.4ms)  SELECT  1 AS one FROM "skills" WHERE "skills"."name" = $1 LIMIT $2  [["name", "twitter"], ["LIMIT", 1]]
  SQL (1.0ms)  INSERT INTO "skills" ("profession_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["profession_id", 1], ["created_at", "2017-12-18 12:22:11.154775"], ["updated_at", "2017-12-18 12:22:11.154775"]]
   (0.1ms)  ROLLBACK

不确定这里发生了什么。

验证错误仍然有效......

有效对象:

 :027 > Skill.new(name: "rails", profession: Profession.first).valid?
  Profession Load (0.4ms)  SELECT  "professions".* FROM "professions" ORDER BY "professions"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Skill Exists (1.9ms)  SELECT  1 AS one FROM "skills" WHERE "skills"."name" = $1 LIMIT $2  [["name", "twitter"], ["LIMIT", 1]]
 => true

检测到验证的名称:

 :020 > Skill.create!(name: String.new, profession: Profession.first)
  Profession Load (0.4ms)  SELECT  "professions".* FROM "professions" ORDER BY "professions"."id" ASC LIMIT $1  [["LIMIT", 1]]
   (0.1ms)  BEGIN
  Skill Exists (0.4ms)  SELECT  1 AS one FROM "skills" WHERE "skills"."name" = $1 LIMIT $2  [["name", ""], ["LIMIT", 1]]
   (0.1ms)  ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
    from (irb):20

最大长度:

:023 > Skill.create!(name: "sjadfkahskdfkjsahdfkjaskjdfkjhsdjkfhksajhfjksahasdljflasjdlfkjaskldjflkasjdklfjklasjdklfjlasjdflkjasklfjsdfhkjsahkjdfhjkasdhfkjhkj", profession: Profession.first)
  Profession Load (0.4ms)  SELECT  "professions".* FROM "professions" ORDER BY "professions"."id" ASC LIMIT $1  [["LIMIT", 1]]
   (0.2ms)  BEGIN
  Skill Exists (0.3ms)  SELECT  1 AS one FROM "skills" WHERE "skills"."name" = $1 LIMIT $2  [["name", "sjadfkahskdfkjsahdfkjaskjdfkjhsdjkfhksajhfjksahasdljflasjdlfkjaskldjflkasjdklfjklasjdklfjlasjdflkjasklfjsdfhkjsahkjdfhjkasdhfkjhkj"], ["LIMIT", 1]]
   (0.3ms)  ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Name is too long (maximum is 50 characters)
    from (irb):23

ProfessionsController

class ProfessionsController < ApplicationController
  def new
    @profession = Profession.new
  end

  def create
    @profession = Profession.find_by(name: profession_params[:name])
    skill_params = get_nested_params(profession_params, :skills_attributes)

    if @profession
      # Save skill under existing profession
      @skill = Skill.create(name: skill_params[:name], profession_id: @profession.id)
    else
      @profession = Profession.new(name: profession_params[:name])
      if @profession.save {
        saved_profession = Profession.find_by(name: profession_params[:name])
        saved_profession.skills.create(name: "twitter")
        # Skill.create(name: skill_params[:name], profession_id: Profession.find_by(name: profession_params[:name])).save!
      }
      end
    end

    respond_to do |format|
      if @profession.save || @skill.save
        format.js { render layout: false }
        format.html { redirect_back fallback_location: root_path, notice: 'Profession was successfully created.' }
      else
        format.html { redirect_back fallback_location: root_path, notice: 'Skill was not created.' }
      end
    end
  end

  private
  def profession_params
    params.require(:profession).permit(:name,
                                       skills_attributes: [:id,
                                                           :name,
                                                           :starting_date,
                                                           :profession_id,
                                                           :_destroy])
  end

  def get_nested_params parent_params, nested_params
    nested_attrs = parent_params[nested_params]
    nested_attrs[nested_attrs.keys[0]]
  end
end

更新 使用saved_profession.skills.create(name: "twitter")

时控制器出错
Started POST "/professions" for 127.0.0.1 at 2017-12-19 01:50:50 +1300
Processing by ProfessionsController#create as JS
  Parameters: {"utf8"=>"✓", "profession"=>{"name"=>"software", "skills_attributes"=>{"1513601431887"=>{"name"=>"rails", "_destroy"=>"false"}}}, "commit"=>"Create Profession"}
  Profession Load (0.3ms)  SELECT  "professions".* FROM "professions" WHERE "professions"."name" = $1 LIMIT $2  [["name", "software"], ["LIMIT", 1]]
   (0.1ms)  BEGIN
  Profession Exists (0.3ms)  SELECT  1 AS one FROM "professions" WHERE "professions"."name" = $1 LIMIT $2  [["name", "software"], ["LIMIT", 1]]
  SQL (0.3ms)  INSERT INTO "professions" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["name", "software"], ["created_at", "2017-12-18 12:50:50.202270"], ["updated_at", "2017-12-18 12:50:50.202270"]]
  Profession Load (0.2ms)  SELECT  "professions".* FROM "professions" WHERE "professions"."name" = $1 LIMIT $2  [["name", "software"], ["LIMIT", 1]]
  Skill Exists (0.3ms)  SELECT  1 AS one FROM "skills" WHERE "skills"."name" = $1 LIMIT $2  [["name", "twitter"], ["LIMIT", 1]]
  SQL (0.7ms)  INSERT INTO "skills" ("profession_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["profession_id", 4], ["created_at", "2017-12-18 12:50:50.205484"], ["updated_at", "2017-12-18 12:50:50.205484"]]
   (0.1ms)  ROLLBACK
Completed 500 Internal Server Error in 8ms (ActiveRecord: 2.2ms)



ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR:  null value in column "name" violates not-null constraint
DETAIL:  Failing row contains (11, null, 2017-12-14, 4, 2017-12-18 12:50:50.205484, 2017-12-18 12:50:50.205484, null).
: INSERT INTO "skills" ("profession_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"):

app/controllers/professions_controller.rb:21:in `block in create'
app/controllers/professions_controller.rb:18:in `create'

1 个答案:

答案 0 :(得分:0)

尝试将get_nested_params修改为:

def get_nested_params(parent_params, nested_params)
  parent_params             # For logging purpose only
  # => {"name"=>"software", "skills_attributes"=>{"1513601431887"=>{"name"=>"rails", "_destroy"=>"false"}}}

  nested_params             # For logging purpose only
  # => :skills_attributes

  nested_attrs = parent_params[nested_params]
  # => {"1513601431887"=>{"name"=>"rails", "_destroy"=>"false"}}

  nested_attrs.values[0]    # Return this
  # => {"name"=>"rails", "_destroy"=>"false"}
end