expecting a hash rather than an instance - ruby-on-rails

I have this error
ArgumentError (wrong number of arguments (1 for 0)):
lib/law/production.rb:20:in `clone'
lib/law/production.rb:20:in `clone_law'
lib/law/production.rb:11:in `initialize'
app/controllers/laws_controller.rb:86:in `new'
app/controllers/laws_controller.rb:86:in `prod_law'
app/controllers/laws_controller.rb:44:in `create'
when using this
module Law
class Production
attr_accessor :law
attr_accessor :creator
def initialize(law,current_user)
#law = law
#creator = current_user
clone_law
end
def current__user
User.find_by_authentication_token(session[:_csrf_token])
end
def clone_law
clone(#law)
end
end
end
where clone, create, prod_law are some methods
I assume Rails is expecting a hash but I don't understand why

Firstly, clone is a standard Ruby method.
Secondly, it expects no arguments at
all (as error message says), it should be called on the object you want to clone, like this:
#law.clone

Related

Rails Console Argument Error Creating a New object

I am new to Rails and Ruby development but I am trying to create an object called Currency which takes in two params and does some calculations on them. I am using attr_accessor to set up the params and I put the file inside the lib directory.
Whenever I run rails console and try to do c = Currency.new(100, "CAD") I get the following error:
ArgumentError: wrong number of arguments (given 2, expected 0)
from (irb):5:in `initialize'
from (irb):5:in `new'
from (irb):5
I did make sure to include the file in application.rb. Here is a skeleton of my class:
class Currency
class << self
attr_accessor :input_value, :currency_iso
USD_ISO = "USD"
USD_TO_DM = 2.8054
def converted_value
convert_to_dm
end
private
def convert_to_dm
#input_value / USD_TO_DM
end
end
end
I have looked all over and I am stumped on what this issue may be. I have tried with and without an initialize method and I have tried creating a more basic version.
The problem here is that you are defining the method as a class method. And you are not defining the initialize method with those two params. Let's check the code below:
class Currency
attr_accessor :input_value, :currency_iso
USD_ISO = "USD"
USD_TO_DM = 2.8054
def initialize(input_value, currency_iso)
#input_value = input_value
#currency_iso = currency_iso
end
def converted_value
convert_to_dm
end
private
def convert_to_dm
input_value / USD_TO_DM
end
end
Also, due to you have already defined the attr_accessor you don't need to use the # when calling those attributes.
I found this post. It can help you to understand better the difference between class method and instance method.

RSpec Shoulda validates_presence_of nilClass

When I use Shoulda's validates_presence_of, it stumbles on a before_validation callback.
before_validation :set_document, :set_product, :set_price
I'm trying to get this spec to pass:
it { should validate_presence_of(:quantity).with_message("Please a quantity.") }
I have database defaults of 0 for a line item's quantity, unit_price, tax_rate, and price. Before a line item is validated I compute the price from the other attributes in case they have changed.
I get this error, and similar errors, for all of the attributes involved in this computation:
3) LineItem
Failure/Error: it { should validate_presence_of(:quantity).with_message("Please a quantity.") }
NoMethodError:
undefined method `*' for nil:NilClass
# ./app/models/line_item.rb:153:in `total_price'
# ./app/models/line_item.rb:223:in `set_price'
# ./spec/models/line_item_spec.rb:32:in `block (2 levels) in <top (required)>'
My callback, set_price, is very simple:
def set_price
self.price = total_price
end
And the total_price method is very simple as well:
def total_price
quantity * unit_price * (1 + tax_rate/100)
end
I'd appreciate any help with this one as I'm completely stumped. I did see some people post about custom validation methods. This seems so basic I can't figure it out how to proceed.
Since total_price runs before validation, quantity can be nil at the time the callback is executed. This is in fact what happens behind the scenes when the Shoulda matcher runs, which is why you get an error. It's trying to send the * method to quantity, which is nil.
Use after_validation or before_save instead.

Rails - really_create_a_version in the model

I'm using the Rails 3 Vestal Versions gem: https://github.com/lailsonbm/vestal_versions
I'd like to create some logic to determine if/when to create a new version on a model update. Per the specs, I did:
class Note < ActiveRecord::Base
versioned :if => :really_create_a_version?
def really_create_a_version
Rails.logger.debug 'really_create_a_version really_create_a_version really_create_a_version really_create_a_version - START'
record.inspect
#note = Note.find(32)
Rails.logger.debug 'really_create_a_version really_create_a_version really_create_a_version really_create_a_version - END'
end
end
But that doesn't work, I get the following error:
NoMethodError (undefined method `really_create_a_version?' for #<Note:0x155c39a28>):
app/controllers/notes_controller.rb:124:in `update'
Any suggestions or ideas? thxs
UPDATE
Conditional version creation. The versioned method now accepts :if and :unless options. Each expects a symbol representing an instance method or a proc that will be evaluated to determine whether or not to create a new version after an update. An array containing any combination of symbols and procs can also be given.
class User < ActiveRecord::Base
versioned :if => :really_create_a_version?
end
Define your method like this
def really_create_a_version?
You are missing the trailing ?

Rails 3 ActiveModel::Serializers seem to need lots of support methods

I'm returning to RoR after not using it for a few years and I'm trying to use ActiveModel to serialise a plain object to XML.
I'm doing the following, as per the comments in activemodel/lib/activemodel/serialization.rb:
class XmlError
include ActiveModel::Serializers::Xml
attr_accessor :code
attr_accessor :description
def attributes
#attributes ||= {'code' => 'nil', 'description' => 'nil'}
end
def initialize(error_code)
#code = error_code
#description = "blah"
self
end
end
I use this in a controller as:
render :xml => XmlError.new("invalid_login")
and I get the following stacktrace:
NoMethodError (undefined method `model_name' for XmlError:Class):
app/controllers/users_controller.rb:19:in `login'
app/controllers/users_controller.rb:5:in `login'
If create a model_name class method, I then get the following stacktrace:
NoMethodError (undefined method `element' for "XmlError":String):
app/controllers/users_controller.rb:19:in `login'
app/controllers/users_controller.rb:5:in `login'
It feels like I'm chasing my tail here. Have I just missed something simple in my class? I followed the example closely.
extend ActiveModel::Naming
is what you are looking for.
http://rdoc.info/github/lifo/docrails/master/ActiveModel/Naming
Why not sub-class ActiveModel::Base?

Wrong number of arguments error with TestMailer

I'm running a strange problem sending emails. I'm getting this exception:
ArgumentError (wrong number of arguments (1 for 0)):
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:642:in `initialize'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:642:in `new'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:642:in `create'
/usr/lib/ruby/gems/1.8/gems/ar_mailer-1.3.1/lib/action_mailer/ar_mailer.rb:92:in `perform_delivery_activerecord'
/usr/lib/ruby/gems/1.8/gems/ar_mailer-1.3.1/lib/action_mailer/ar_mailer.rb:91:in `each'
/usr/lib/ruby/gems/1.8/gems/ar_mailer-1.3.1/lib/action_mailer/ar_mailer.rb:91:in `perform_delivery_activerecord'
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.1.1/lib/action_mailer/base.rb:508:in `__send__'
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.1.1/lib/action_mailer/base.rb:508:in `deliver!'
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.1.1/lib/action_mailer/base.rb:383:in `method_missing'
/app/controllers/web_reservations_controller.rb:29:in `test_email'
In my web_reservations_controller I have a simply method calling
TestMailer.deliver_send_email
And my TesMailer is something like:
class TestMailer < ActionMailer::ARMailer
def send_email
#recipients = "xxx#example.com"
#from = "xxx#example.com"
#subject = "TEST MAIL SUBJECT"
#body = "<br>TEST MAIL MESSAGE"
#content_type = "text/html"
end
end
Do you have any idea?
Thanks!
Roberto
The problem is with the model that ar_mailer is using to store the message. You can see in the backtrace that the exception is coming from ActiveRecord::Base.create when it calls initialize. Normally an ActiveRecord constructor takes an argument, but in this case it looks like your model doesn't. ar_mailer should be using a model called Email. Do you have this class in your app/models directory? If so, is anything overridden with initialize? If you are overriding initialize, be sure to give it arguments and call super.
class Email < ActiveRecord::Base
def initialize(attributes)
super
# whatever you want to do
end
end
Check that email_class is set correctly: http://seattlerb.rubyforge.org/ar_mailer/classes/ActionMailer/ARMailer.html#M000002
Also don't use instance variables. Try:
class TestMailer < ActionMailer::ARMailer
def send_email
recipients "roberto.druetto#gmail.com"
from "roberto.druetto#gmail.com"
subject "TEST MAIL SUBJECT"
content_type "text/html"
end
end
From the docs: the body method has special behavior. It takes a hash which generates an instance variable named after each key in the hash containing the value that that key points to.
So something like this added to the method above:
body :user => User.find(1)
Will allow you to use #user in the template.

Resources