Ruby/Rails: accessing a variable inside a .each on my instance variable array causing Ruby interpreter to crash
I've written a mixin (based on something I read in a blog) that seems to be causing a problem
Here is a link to the project: http://www.filehosting.org/file/details/263759/onlinescheduler.zip (or send me an email: aaron.a.ashworth@gmail.com and I'll email it) and I've stripped as much out as I can for it to still cause the problem. The key files to look at are:
/lib/user_role.rb (near line 11)
/app/views/customers/index.html.erb (near line 16)
/app/controllers/customers_controller.rb (near line 47)
I'll layout the important stuff here as well:
/lib/user_role.rb:
module UserRole
def self.included(base)
base.has_one :user, :as => :user_role, :autosave => true
base.validate :user_must_be_valid
base.alias_method_chain :user, :autobuild
base.extend ClassMethods
base.define_user_accessors
end
def user_with_autobuild
user_without_autobuild || build_user
end
def method_missing(meth, *args, &blk)
user.send(meth, *args, &blk)
rescue NoMethodError
super
end
module ClassMethods
def define_user_accessors
all_attributes = User.content_columns.map(&:name) + ["password", "password_confirmation"]
ignored_attributes = ["created_at", "updated_at", "user_role_type"]
attributes_to_delegate = all_attributes - ignored_attributes
attributes_to_delegate.each do |attrib|
class_eval <<-RUBY
def #{attrib}
user.#{attrib}
end
def #{attrib}=(value)
self.user.#{attrib} = value
end
def #{attrib}?
self.user.#{attrib}?
end
RUBY
end
end
end
protected
def user_must_be_valid
Logger.new(STDOUT).info('calling user_must_be_valid')
unless user.valid?
user.errors.each do |attr, message|
errors.add(attr, message)
end
end
end
end
app/views/customers/index.html.erb:
...
<% @customers.each do |customer| %>
<tr>
<td><%= customer.account_id %></td>
...
accessing customer
at all causes the problem. I can do anything to @customers
but as soon as I try to access customer....
or even @customers[0]....
I get a problem.
Steps to produce
1) After unzipping the file, go into the root directory in terminal and run these commands:
bundle install
bundle exec rake db:drop
bundle exec rake db:migrate
rails s
2) Open your browser to localhost:3000/customers
and click New Customer
3) Fill in the form you see like so:
Account: 3
First Name: First
Last Name: Last
Email: first.last@domain.com
Password: 1234
Password confirmation: 1234
4) Click the Create Customer
button.
Expected Behavior
You should be redirected to localhost:3000/customers/1
Current Behaviour
The webserver crashes as you get the following message:
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x17b356) [0x7fef4a97e356]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x1713ee) [0x7fef4a9743ee]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x177243) [0x7fef4a97a243]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(rb_vm_invoke_proc+0x9f) [0x7fef4a97b08f]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x17b644) [0x7fef4a97e644]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x1713ee) [0x7fef4a9743ee]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x177243) [0x7fef4a97a243]
~/.rvm/rubies开发者_如何学编程/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x1784f4) [0x7fef4a97b4f4]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x178cb5) [0x7fef4a97bcb5]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x17b50d) [0x7fef4a97e50d]
~/.rvm/rubies/ruby-1.9.2-p290/lib/libruby.so.1.9(+0x1713ee) [0x7fef4a9743ee]
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Rerunning the webserver and going to localhost:3000/customers
sometimes gives you a different error. A segmentation fault and it complains about /lib/user_role.rb:11
Environment
Ruby 1.9.2-p290
Rails 3.0.9
RVM 1.8.1
Ubuntu 11.04
Edit
Something to note: If you try working the same code that bombs in console it seems fine. Example:
(After entering rails c)
@customers = Customer.all
@customers.each do |customer|
p customer.account_id
end
# this doesn't cause an error or crash.
@customer[0].first_name
=> "First"
If you remove:
def method_missing(meth, *args, &blk)
customer.send(meth, *args, &blk)
rescue NoMethodError
super
end
and
def method_missing(meth, *args, &blk)
user.send(meth, *args, &blk)
rescue NoMethodError
super
end
from the x_role files in your lib directory, it should work fine. On a side note look into inherited resource for your controllers and simple form for your forms.
精彩评论