I've got a ruby exercise, and cannot quite get past one point. When I run the tests, it throws undefined method "attribute" for CommentSerializer:Class
. Though, there is such a method defined in serializer.rb
, from which it's being inherited.
Am I missing something about inheritance in ruby here?
Note : I am neither allowed to add any gems other than the two listed below, nor to modify any file other than serializer.rb
.
Here are the files:
Gemfile:
gem 'rspec'
gem 'pry'
app/comment.rb:
Comment = Struct.new(:id, :body)
app/comment_serializer.rb:
require_relative "serializer"
class CommentSerializer < Serializer
attribute :id
attribute :body
end
app/serializer.rb:
class Serializer
def initialize(object)
@obj = object
end
def serialize
obj.members.inject({}) do |hash, member|
hash[member] = obj[member]
hash
end
end
def attribute(key)
end
private
def obj
@obj
end
end
spec/comment_serializer_spec.rb:
require "date"
require_relative "spec_helper"
require_relative "../app/comment"
require_relative "../app/comment_serializer"
RSpec.describe CommentSerializer do
subject { described_class.new(comment) }
let(:comment) do
Comment.new(1, "Foo bar")
end
it "serializes object" do
expect(subject.serialize).to eq({
id: 1,
body: "Foo bar",
})
end
end
If you call something like attribute
in the body of the class
definition then it happens in the class context at that exact moment , as in:
class Example < Serializer
# This is evaluated immediately, as in self.attribute(:a) or Example.attribute(:a)
attribute :a
end
There must be a corresponding class method to receive that call, as in:
class Serializer
def self.attribute(name)
# ...
end
end
Since you're inheriting that method it will be defined prior to calling it, but that's not the case if you have something like:
class Example
attribute :a # undefined method `attribute' for Example:Class (NoMethodError)
def self.attribute(name)
end
end
The method is defined after it's called, so you get this error. You must either reverse the order, define first, call second, or put it into a parent class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.