【问题标题】:Rails : wrong number of arguments (1 for 0) for .newRails:.new 的参数数量错误(1 代表 0)
【发布时间】:2014-06-25 14:22:04
【问题描述】:

当我尝试创建 Review 对象时出现此错误:

ArgumentError in ReviewsController#create

wrong number of arguments (1 for 0)

app/controllers/reviews_controller.rb:17:in `new'
app/controllers/reviews_controller.rb:17:in `create'

我不明白我做错了什么?我可以创建任何其他对象,但这些对象给了我这个错误,不管我做什么。我尽量不争辩,但它仍然认为有一个......

我的模特Review

# -*- encoding : utf-8 -*-
class Review < ActiveRecord::Base

  attr_accessible :global_validation_date, :hr_comment, :hr_validate, :hr_validator, :manager_comment, :manager_validate, :manager_validation_date, :manager_validator, :owner_satisfaction, :owner_validate, :owner_validation_date, :send, :user_id

  belongs_to :user
  has_many :review_projects, dependent: :destroy

end

我的控制器ReviewsController

# -*- encoding : utf-8 -*-
class ReviewsController < ApplicationController

  before_filter :authenticate_user!
  before_filter :check_permissions, only: :create

  def index
    @user = User.find(params[:user_id])
    @reviews = @user.reviews
  end

  def create
    @user = User.find(params[:user_id])
    @reviews = @user.reviews
    if @reviews.empty? || check_last_validate

      @review = Review.new   # HERE IS MY ERROR

      if @review.save
        render 'index', notice: "Review successfully created"
      else
        render 'index', notice: "An error occured on saving, please try again"
      end
    else
      render 'index', alert: "You have to validate previous review before create a new one."
    end

    redirect_to user_reviews_path
  end

  private

  def check_permissions
    render_access_forbidden unless current_user == User.find(params[:user_id])
  end

  def check_last_validate
    if !@reviews.empty?
      return (@reviews.last.hr_validate || @reviews.last.manager_validate)
    else
      return false
    end
  end

end

我在 SO 上阅读了所有相同的问题,但没有任何效果。我小心错字,但我不认为我做错了。

我尝试了三种方法来创建我的对象Review

@review = Review.new
@review.user_id = current_user.id
@review.hr_validator = ((current_user.hr_id.nil?) ? current_user.id : current_user.hr_id )
@review.manager_validator = ((current_user.manager_id.nil?) ? current_user.id : current_user.manager_id )
@review.hr_validate = false
@review.manager_validate = false
@review.owner_validate = false
@review.hr_comment = ""
@review.manager_comment = ""
@review.owner_satisfaction = nil
@review.send = false

@review = Review.new(
  user_id: current_user.id,
  hr_validator: ((current_user.hr_id.nil?) ? current_user.id : current_user.hr_id ),
  manager_validator: ((current_user.manager_id.nil?) ? current_user.id : current_user.manager_id ),
  hr_validate: false,
  manager_validate: false,
  owner_validate: false,
  hr_comment: "",
  manager_comment: "",
  owner_satisfaction: nil,
  send: false )

@user.reviews.create!(
  user_id: current_user.id,
  hr_validator: ((current_user.hr_id.nil?) ? current_user.id : current_user.hr_id ),
  manager_validator: ((current_user.manager_id.nil?) ? current_user.id : current_user.manager_id ),
  hr_validate: false,
  manager_validate: false,
  owner_validate: false,
  hr_comment: "",
  manager_comment: "",
  owner_satisfaction: nil,
  send: false )

最后一个给我同样的错误除了:

wrong number of arguments (2 for 0)

我的 ruby​​ 版本是 1.9.3,我的 rails 版本是 3.2.13

谢谢。

编辑:

当我在 Rails 控制台中尝试此代码时:

current_user = User.first # as you are inside rails console you wont have current_user available to you
@review = Review.new(user_id: current_user.id,
                    hr_validator: ((current_user.hr_id.nil?) ? current_user.id : current_user.hr_id ),
                    manager_validator: ((current_user.manager_id.nil?) ? current_user.id : current_user.manager_id ),
                    hr_validate: false,
                    manager_validate: false,
                    owner_validate: false,
                    hr_comment: "",
                    manager_comment: "",
                    owner_satisfaction: nil,
                    send: false )
@review.save

我得到这个错误:

ArgumentError: wrong number of arguments (2 for 0)
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/activerecord-3.2.13/lib/active_record/attribute_methods/read.rb:71:in `__temp__'
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes'
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `each'
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/activerecord-3.2.13/lib/active_record/base.rb:498:in `initialize'
    from (irb):31:in `new'
    from (irb):31
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /Users/killian/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

【问题讨论】:

  • 这是您的整个 Review 模型吗?您是否在模型中覆盖了def initialize
  • 是的,这是我的整个 Review 模型。而且我不会覆盖initialize 方法。如果我没有覆盖 newinitialize 方法,我到处搜索,但我没有找到任何东西。
  • @Kilian 在您的 check_last_validate 方法中,return (@reviews.last.hr_validate || @reviews.last.manager_validate) 想要做什么?而且你没有正确初始化你的评论,你没有任何参数
  • 我通过 id 订购用户的评论(has_many :reviews, order: 'id ASC', dependent: :destroyUser 模型中)以验证最后的评论是否得到验证。但是我已经尝试摆脱所有条件,但它仍然不起作用。即使我尝试在rails console 中使用简单的一行。
  • 哦?但是我测试了这个方法,它返回给我一个值,所以我认为它可以正常工作。无论如何,我尝试只将@review = Review.new@review.saveredirect_to 放在def create 中以隔离问题,但它仍然不起作用。

标签: ruby-on-rails ruby ruby-on-rails-3 argument-error


【解决方案1】:

好的,我找到了问题...显然错误是由属性send 引起的。我真的很惊讶,因为我检查了 ruby​​ 中的所有保留字并且“发送”没有出现在任何地方。

所以只需要重命名它,现在一切正常。总之,谢谢大家的帮助。

【讨论】:

  • send 内置于 ruby​​ 语言中。当你在一个对象上调用一个方法时,你实际上是在向它send发送一条消息,其中包含要调用的方法的名称。 ruby-doc.org/core-2.1.1/Object.html#method-i-send
  • send 主要用于 ruby​​ 中,用于在带有字符串的对象上调用方法。例如,Cat.send("meow"),如果 Cat 类有 meow 方法。当您有多个 ruby​​ 方法并且需要调用由您可以访问的不断变化的字符串变量确定的正确方法时,它很有用。您可以在您的发送方法中插入字符串参数,而不是执行冗长的ifelse 语句。比如action = "meow" || "eat" || "sleep",那么你可以说Cat.send("#{action}"),假设你有这三个方法。
【解决方案2】:

我假设您的审阅模型中没有任何验证,如 your hr_comment, manager_comment and owner_satisfaction are not initialised,如果您对这些字段有类似 presence: true 的内容,那么您的记录将不会保存在数据库中。在您的 rails 控制台中试试这个:

current_user = User.first # as you are inside rails console you wont have current_user available to you
@review = Review.new(user_id: current_user.id,
                    hr_validator: ((current_user.hr_id.nil?) ? current_user.id : current_user.hr_id ),
                    manager_validator: ((current_user.manager_id.nil?) ? current_user.id : current_user.manager_id ),
                    hr_validate: false,
                    manager_validate: false,
                    owner_validate: false,
                    hr_comment: "",
                    manager_comment: "",
                    owner_satisfaction: nil,
                    send: false )
@review.save

【讨论】:

  • 我尝试了它并得到错误:ArgumentError: wrong number of arguments (2 for 0) 我没有验证或默认值。我去编辑帖子以放置整个错误消息。
  • @Kilian 虽然它不应该但不传递三元运算符,你可以尝试在 hr_validator 和 manager_validator 字段中传递样本值,如果你有user has_many :reviews,那么你可以简单地做current_user.review.new(parameters) 和不需要在参数中传递 user_id 值,rails 会自动关联它
  • 我试过了,还是不行...这没有任何意义...(但感谢current_user.review.new(parameters) 的建议,因为我认为它只适用于.create)跨度>
  • @Kilian 这就是你的 Review 模型吗?你可能已经覆盖了新方法
  • 是的。这就是为什么我不理解这个错误,我从不尝试覆盖 new 方法。我以完全相同的方式创建了一个ReviewProject 模型,我对此没有任何问题。
猜你喜欢
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多