【问题标题】:Query in Active Record Rails does not workActive Record Rails 中的查询不起作用
【发布时间】:2017-11-22 22:21:41
【问题描述】:

我正在尝试使用 Rails 的活动记录生成 before_save 并将其保存到字段中。它使用两个表(消息和规范)

我的模型/message.rb 文件如下所示:

class Message < ApplicationRecord
  has_many :specs
  accepts_nested_attributes_for :specs
  before_save :generate_output

  def generate_output
    self.output = "hola"
    specs_array = Spec.where(message_id: self.id).order('id asc')
    specs_array.each do |spec|
        self.output = "hello"
        if spec.call
          self.output += Message.find(name: spec).output
        else
          self.output += spec.specification
        end
      end
    self.output
  end
end

还有我的模型/spec.rb 文件:

class Spec < ApplicationRecord
  belongs_to  :message
end

这是我的架构:

ActiveRecord::Schema.define(version: 20171121153642) do
  enable_extension "plpgsql"

  create_table "messages", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.text "output"
  end

  create_table "specs", force: :cascade do |t|
    t.string "specification"
    t.boolean "call"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "message_id"
    t.index ["message_id"], name: "index_specs_on_message_id"
  end

  add_foreign_key "specs", "messages"
end

我有一个消息表单,在提交时,将一个“名称”保存到消息表,并将 3 个规范(及其 message_id)保存到规范表。它还应该根据消息表中的规范生成并保存输出(如您在消息模型中所见)。

但是模型中的这两行代码不起作用:

    specs_array = Spec.where(message_id: self.id).order('id asc')
    specs_array.each do |spec|

我知道他们之前的那些正在工作,因为当我创建一条新消息时,它的输出保存为“hola”,如果这两行有效,它应该保存为“hello”+无论消息是什么。

我已经在 Rails 控制台中尝试过查询,它完全可以正常工作,知道为什么它不能在应用程序中工作吗? 谢谢!

编辑: 我需要保存的控制器方法(它是 Rails 通用方法):

  def create
    @message = Message.new(message_params)

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

以及messasge_params的私有方法:

def message_params
  params.require(:message).permit(:name, specs_attributes: [:id, :call, :specification])
end

【问题讨论】:

  • 如果您创建了 Message 实例,则在 before_save 回调中没有 id
  • 您使用before_save 操作,在这种情况下,当您调用Spec.where(message_id: self.id).order('id asc') 这些规格尚未保存到数据库中
  • 哦,我明白了....任何想法如何解决这个问题?
  • 您在before_save 中尝试做的事情可以在消息控制器操作本身中实现。您可以在收到表单输入后轻松创​​建规范以及消息。正如您在Message 中定义的accepts_nested_attributes_for :specsparams 将在specs_attributes 中包含与规格相关的字段。保存消息也会保存相关的规格。详情:api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/…
  • 您正在尝试在保存记录之前查询数据库中的记录... :'-)

标签: ruby-on-rails ruby postgresql activerecord


【解决方案1】:

尝试改写你喜欢的:

specs_array = Spec.where(message_id: self.id).order('id asc')

收件人:

specs_array = specs.order(:id)

写评论是否有帮助?

【讨论】:

  • self 在这里是不必要的。
  • 不幸的是,它不起作用:/ 和以前一样,没有任何反应,输出保存为 'hola'
  • @NavidFalla 您能否在问题中包含您的控制器方法?调用保存消息/规范的那个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
相关资源
最近更新 更多