在保存多对多关系时获取ActiveRecord :: RecordInvalid

时间:2018-06-19 19:40:32

标签: ruby-on-rails ruby

我有以下模型来描述步骤和产品之间的多对多关系:

class Step < ApplicationRecord
  has_and_belongs_to_many :products
end

class Product < ApplicationRecord
  has_and_belongs_to_many :steps
end

class ProductsStep < ApplicationRecord
  belongs_to :product
  belongs_to :step
end

这些是我的桌子:

步骤:

   Column    |            Type             |                     Modifiers                      | Storage  | Stats target | Description 
-------------+-----------------------------+----------------------------------------------------+----------+--------------+-------------
 id          | bigint                      | not null default nextval('steps_id_seq'::regclass) | plain    |              | 
 name        | character varying           | not null                                           | extended |              | 
 created_at  | timestamp without time zone |                                                    | plain    |              | 
 updated_at  | timestamp without time zone |                                                    | plain    |              | 
Indexes:
    "steps_pkey" PRIMARY KEY, btree (id)
    "index_steps_on_weeks_id" btree (weeks_id)

产品:

      Column       |            Type             |                       Modifiers                       | Storage  | Stats target | Description 
--------------------+-----------------------------+-------------------------------------------------------+----------+--------------+-------------
 id                 | bigint                      | not null default nextval('products_id_seq'::regclass) | plain    |              | 
 name               | character varying           | not null                                              | extended |              | 
 photo_file_name    | character varying           |                                                       | extended |              | 
 photo_content_type | character varying           |                                                       | extended |              | 
 photo_file_size    | integer                     |                                                       | plain    |              | 
 photo_updated_at   | timestamp without time zone |                                                       | plain    |              | 
 created_at         | timestamp without time zone | not null                                              | plain    |              | 
 updated_at         | timestamp without time zone | not null                                              | plain    |              | 
Indexes:
    "products_pkey" PRIMARY KEY, btree (id)

产品步骤:

   Column   |            Type             | Modifiers | Storage | Stats target | Description 
------------+-----------------------------+-----------+---------+--------------+-------------
 step_id    | integer                     | not null  | plain   |              | 
 product_id | integer                     | not null  | plain   |              | 
 created_at | timestamp without time zone | not null  | plain   |              | 
 updated_at | timestamp without time zone | not null  | plain   |              | 
Indexes:
    "products_steps_pkey" PRIMARY KEY, btree (product_id, step_id)

我想保存相关步骤的产品,但是我收到以下消息:

  

在81毫秒内完成422个不可处理的实体(ActiveRecord:10.6毫秒)

     

ActiveRecord :: RecordInvalid(验证失败:步骤无效)

我做了以下事情:

def create
    steps = Array.new()
    params[:product][:steps].split(/,/).each do |s|
      steps << s.to_i
    end
    @product = Product.new(product_params)
    @product.steps << Step.where(:id => steps)

    puts "#{@product.steps.first.name}" #the name is printed
    product = Product.find_by(name: @product.name, brand: @product.brand)
    if product.nil?
      if @product.save!
        render :json => {:status => :success}
      end
    end
  end

steps参数是一个类似于“ 1,2,3”的字符串,它表示步骤ID。

我不知道自己做错了什么,在其他情况下我做的完全一样,而且奏效了。

编辑:

这是我所有的请求和错误消息,包括未通过的验证:

Bad request content body
Started POST "/products/?product[name]=test+1&product[brand]=test&product[released_for]=Low+Poo&product[weight]=50.0&product[measurement]=g&product[steps]=1%2C2%2C3&product[user_id]=test%40gmail.com&" for 192.168.2.5 at 2018-06-19 17:56:23 -0300
Processing by ProductsController#create as HTML
  Parameters: {"product"=>{"name"=>"test 1", "brand"=>"test", "released_for"=>"Low Poo", "weight"=>"50.0", "measurement"=>"g", "steps"=>"1,2,3", "user_id"=>"test@gmail.com"}}
Unpermitted parameter: :steps
  Step Load (0.4ms)  SELECT "steps".* FROM "steps" WHERE "steps"."id" IN ($1, $2, $3)  [["id", 1], ["id", 2], ["id", 3]]
  ↳ app/controllers/products_controller.rb:73
------LOGS-------
#<ActiveModel::Errors:0x007f2840acb628 @base=#<Product id: nil, name: "Test 1", brand: "Test", measurement: "g", weight: #<BigDecimal:7f28409f2ee0,'0.5E2',9(18)>, photo_file_name: nil, photo_content_type: nil, photo_file_size: nil, photo_updated_at: nil, released_for: "Low Poo", created_at: nil, updated_at: nil, user_id: "test@gmail.com">, @messages={:steps=>["não é válido"]}, @details={:steps=>[{:error=>:invalid}, {:error=>:invalid}, {:error=>:invalid}]}>
-------------
Hidratação
  Product Load (0.3ms)  SELECT  "products".* FROM "products" WHERE "products"."name" = $1 AND "products"."brand" = $2 LIMIT $3  [["name", "Test 1"], ["brand", "Test"], ["LIMIT", 1]]
  ↳ app/controllers/products_controller.rb:78
#<ActiveModel::Errors:0x007f2840acb628 @base=#<Product id: nil, name: "Test 1", brand: "Test", measurement: "g", weight: #<BigDecimal:7f28409f2ee0,'0.5E2',9(18)>, photo_file_name: nil, photo_content_type: nil, photo_file_size: nil, photo_updated_at: nil, released_for: "Low Poo", created_at: nil, updated_at: nil, user_id: "test@gmail.com">, @messages={:steps=>["não é válido"]}, @details={:steps=>[{:error=>:invalid}, {:error=>:invalid}, {:error=>:invalid}]}>
   (0.2ms)  BEGIN
  ↳ app/controllers/products_controller.rb:82
   (0.2ms)  ROLLBACK
  ↳ app/controllers/products_controller.rb:82
Completed 422 Unprocessable Entity in 75ms (ActiveRecord: 9.4ms)



ActiveRecord::RecordInvalid (A validação falhou: Steps não é válido):

app/controllers/products_controller.rb:82:in `create'

2 个答案:

答案 0 :(得分:1)

根据共享的描述,似乎以下提到的问题之一可能引发了异常。

首先,下面提到的日志记录显示,除了将所有其他参数都允许数据库外,只允许步骤。

Parameters: {"product"=>{"name"=>"test 1", "brand"=>"test", "released_for"=>"Low Poo", "weight"=>"50.0", "measurement"=>"g", "steps"=>"1,2,3", "user_id"=>"test@gmail.com"}}
Unpermitted parameter: :steps

因此,user_id列是否具有数据类型字符串,在共享的表结构中也找不到user_id列。

第二,对于ActiveRecord :: RecordInvalid,当对相应模型的验证失败时会引发此问题。

请检查上述情况是否发生验证失败。

答案 1 :(得分:0)

验证失败:步骤无效。这意味着您传递的步骤ID无效。您可以打印@product和@ product.steps来检查正在打印什么。当我检查代码@product.steps << Step.where(:id => steps)时,此代码将组成array数组,因此它必须为@product.steps = Step.where(:id => steps)@product.steps += Step.where(:id => steps)。打印@product和@ product.steps,可以清楚地说明要在表中保存哪些数据。