Rails : wrong number of arguments (1 for 0) for .new
Asked Answered
O

2

8

I have this error when I try to create a Review object :

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'

I don't understand what I am doing wrong ? I can create any others objects, but these one give me this error, doesn't matter what I do. I try to put no argument but it still consider there is one...

My model 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

My controller 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 [email protected]?
      return (@reviews.last.hr_validate || @reviews.last.manager_validate)
    else
      return false
    end
  end

end

I read all same questions on SO, but nothing works. I be careful on typo, but I don't think I did a mistake.

I tried three ways to create my object 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 )

The last one give me the same error except :

wrong number of arguments (2 for 0)

My ruby version is 1.9.3, my rails version is 3.2.13

Thanks.

EDIT :

When I try in my rails console this code :

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

I get this error :

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>'
Overtrump answered 25/6, 2014 at 14:22 Comment(7)
Is that your entire Review model? Are you perhaps overriding def initialize within your model?Uxorious
Yes it is my entire Review model. And I don't override initialize method. I searched everywhere if I didn't override new or initialize method but I didn't find anything.Overtrump
@Overtrump what are you trying to do by return (@reviews.last.hr_validate || @reviews.last.manager_validate) in your check_last_validate method? and you are not initialising your review properly, you don't have anything in parametersMargiemargin
I order user's reviews by id (with has_many :reviews, order: 'id ASC', dependent: :destroy in User model) to verify if the last review is validated or not. But I already try to get off all conditions and it still doesn't work. Even when I try with a simple line in rails console.Overtrump
Oh ? But I tested this method and it return to me one value, so I think it works correctly. Anyway, I try to put only @review = Review.new, @review.save and the redirect_to in def create to isolate the problem, and it still doesn't work.Overtrump
This may or may not be the cause of your problem, but I would not have a column named send, as this could conflict with the ruby dispatch mechanism.Sullyprudhomme
@Sullyprudhomme have send attributes in my file structure.sql and in the attr_accessible. I thought I used a reserved word, but apparently not. I also try to rename Review model, and same problem. So it can come from one of its attributes.Overtrump
O
17

Ok I find the problem... Apparently the error was caused by the attribute send. I'm really surprise because I checked all reserved words in ruby and "send" doesn't appear anywhere.

So just have to rename it and everything works now. Anyhow, thanks all for your help.

Overtrump answered 26/6, 2014 at 11:11 Comment(2)
send is build into the ruby language. When you invoke a method on an object, you are really sending a message to it, with the name of the method to invoke. ruby-doc.org/core-2.1.1/Object.html#method-i-sendSullyprudhomme
send is mostly used in ruby for invoking methods on objects with strings. For example, Cat.send("meow"), if the Cat class had a meow method. Its useful when you have more than one ruby method and need to call the right one which is determined by a changing string variable you have access to. Instead of doing a long if and else statement you can interpolate the string argument in your send method. For example, action = "meow" || "eat" || "sleep", then you can say Cat.send("#{action}"), assuming you have those three methods.Paleolithic
M
0

I'm assuming you don't have any validations in your review model as your hr_comment, manager_comment and owner_satisfaction are not initialised, if you have something like presence: true for these fields then your record will not save in database.Try this in your rails console:

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
Margiemargin answered 25/6, 2014 at 16:0 Comment(6)
I try it and get error : ArgumentError: wrong number of arguments (2 for 0) and I have no validation or default value. I go edit ma post to put the entire error message.Overtrump
@Overtrump although it shouldn't but instead of passing a ternary operator can you try passing sample values in hr_validator and manager_validator fields and also if you have user has_many :reviews then you can simply do current_user.review.new(parameters) and need not pass user_id value in parameters, rails will associate it automaticallyMargiemargin
I try that, still doesn't work... It makes no sens... (But thanks for the advise about current_user.review.new(parameters) because I thought it works only with .create)Overtrump
@Overtrump is this all of your Review model? you may have override new methodMargiemargin
Yes it is. That is why I don't understand this error, I never try to override new method. I create a ReviewProject model exactly the same way, and I've no problem with it.Overtrump
I don't understand why it thinks I pass a parameter whereas I don't.Overtrump

© 2022 - 2024 — McMap. All rights reserved.