0

我很难过。在之前的提交中,我为特定模型提交新记录的表单工作得很好,但我一定是做了一些事情弄乱了它,因为现在我的控制器只是在我提交表单时呈现“新”操作。

验证都通过了,但由于某种原因,记录没有保存。

我在开发过程中没有编写测试,我现在很后悔,因为我要回去编写它们。

但由于我是 Rails 新手,我只想问一下调试它的最佳方法是什么。我试过查看我的本地服务器日志,但它没有提供任何帮助。我的控制器的创建操作如下:

def create
    @product = Product.find(params[:product_id])
    @review = @product.reviews.new(params[:review])
    current_user.reviews << @review
    if @review.save
        flash[:notice] = "Successfully created review."
        redirect_to current_user
    else
        render :action => 'new'
    end
end

抱歉,这是非常模糊的(如果是,我将删除问题)

另外需要注意的是,我的模型现在都没有保存,所以这似乎是一个应用程序范围的问题,因为它们都在较早的提交中工作。

4

3 回答 3

4

在调试这样的事情方面,我推荐两个 gem:better_errorspry. 两者任一。最好两者兼而有之。

更好的错误

https://github.com/charliesome/better_errors 只需将其添加到您的 gemfile 中即可:

group :development do
  gem 'better_errors'
  gem 'binding_of_caller'
end

在您的控制器中引发错误,您将在引发异常的那一刻被转储到 IRB 会话中。然后你可以四处逛逛,直接看看发生了什么。

http://pryrepl.org/

同样,只需安装 gem:

宝石“撬轨”

然后重新启动您的服务器(rails s直接使用 - 乘客或工头可能会搞砸)并binding.pry从您的控制器调用:

def create
    @product = Product.find(params[:product_id])
    @review = @product.reviews.new(params[:review])
    current_user.reviews << @review

    binding.pry # <---- You will get dumped right here
    if @review.save
        flash[:notice] = "Successfully created review."
        redirect_to current_user
    else
        render :action => 'new'
    end
end

当您提交表单时,服务器将停止,您应该在该行被转储到控制台中。然后你可以四处寻找——检查所有变量,调用@review.save 看看会发生什么。

Pry 有很多功能,您可以在其中进行检查。

您可以将 better_errors 配置为默认使用 pry。

哦,规格很好:D

于 2013-06-06T04:28:09.980 回答
1

1.如果您希望在评论上设置product_id,您的产品应该是现有记录。如果没有,你可以简单地做

Review.new(params[:review])

代替

@product = Product.new(params[:product])
@review = @product.reviews.new(params[:review])

2.current_user.reviews << @review 在数据库中创建带有 current_user_id 的评论记录。您不必再次执行@review.save。

3.做@review.save!去测试。如果保存记录有问题,它将引发异常。

于 2013-06-06T03:25:14.823 回答
1

您实例化一个新对象然后保存它的顺序并不完全正确。

而不是在保存之前附加您未提交@reviewcurrent_user.reviews内容,您应该只根据它是否正确保存有条件地附加它。

完成您正在尝试的事情的Rails 方式类似于以下内容:

def create
    @product = Product.find(params[:product_id])
    @review = @product.reviews.build(params[:review])
    if @review.save
        current_user.reviews << @review
        flash[:notice] = "Successfully created review."
        redirect_to current_user
    else
        render :action => :new
    end
end

这样,如果@review.save返回false,您将知道某些内容是无效的,因为:action => :new将被渲染。

编辑:

由于您希望在没有规范的情况下进行调试,因此您可以尝试使用该save!方法。它实际上不是false在失败时返回,而是抛出一个异常(这对于调试来说非常方便):

@review.save!
#=> ActiveRecord::RecordInvalid: Validation failed: `reason for validation failure`
于 2013-06-06T04:19:42.110 回答