Skip to content

Commit

Permalink
[Doc] Modify README for version 3
Browse files Browse the repository at this point in the history
"Prefer methods on resource" is now "Methods conflict"
  • Loading branch information
okuramasafumi committed Oct 15, 2023
1 parent 2fde6a1 commit e3b8eca
Showing 1 changed file with 44 additions and 39 deletions.
83 changes: 44 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,72 +291,77 @@ class UserResource
end
```

#### Prefer methods on resource
#### Methods conflict

By default, Alba prefers methods on the object to methods on the resource. This means if you have a following situation:
Consider following code:

```ruby
class User
attr_accessor :id, :name, :email

def initialize(id, name, email)
@id = id
@name = name
@email = email
end

def name_with_email
'dummy!'
class Foo
def bar
"This is Foo"
end
end

class UserResource
class FooResource
include Alba::Resource

root_key :user, :users # Later is for plural

attributes :id, :name, :name_with_email
attributes :bar

# Same method exists in `User` class!
# This is not called
def name_with_email(user)
"#{user.name}: #{user.email}"
def bar
"This is FooResource"
end
end

user = User.new(1, 'Masafumi OKURA', 'masafumi@example.com')
UserResource.new(user).serialize
# => '{"user":{"id":1,"name":"Masafumi OKURA","name_with_email":"dummy!"}}'
FooResource.new(Foo.new).serialize
```

You can see that `name_with_email` is now `dummy!` from `User#name_with_email`. You cna change this behavior by using `prefer_resource_method!` DSL in a resource class:
By default, Alba create the JSON as `'{"bar":"This is FooResource"}'`. This means Alba calls a method on a Resource class and doesn't call a method on a target object. This rule is applied to methods that are explicitly defined on Resource class, so methods that Resource class inherits from `Object` class such as `format` are ignored.

```ruby
# With the same `User` class
class Foo
def format
"This is Foo"
end
end

class UserResource
class FooResource
include Alba::Resource

prefer_resource_method! # This line is important
attributes :bar

root_key :user, :users # Later is for plural
# Here, `format` method is available
end

attributes :id, :name, :name_with_email
FooResource.new(Foo.new).serialize
# => '{"bar":"This is Foo"}'
```

# Same method exists in `User` class!
# But now this is called!
def name_with_email(user)
"#{user.name}: #{user.email}"
If you'd like Alba to call methods on a target object, use `prefer_object_method!` like below.

```ruby
class Foo
def bar
"This is Foo"
end
end

user = User.new(1, 'Masafumi OKURA', 'masafumi@example.com')
UserResource.new(user).serialize
# => '{"user":{"id":1,"name":"Masafumi OKURA","name_with_email":"Masafumi OKURA: masafumi@example.com"}}'
```
class FooResource
include Alba::Resource

prefer_object_method! # <- important

The next major version of Alba will change this default behavior to prefer resource methods. In case you want to preserve current behavior, there's `prefer_object_method!` DSL, which does that.
attributes :bar

# This is not called
def bar
"This is FooResource"
end
end

FooResource.new(Foo.new).serialize
# => '{"bar":"This is Foo"}'
```

#### Params

You can pass a Hash to the resource for internal use. It can be used as "flags" to control attribute content.
Expand Down

0 comments on commit e3b8eca

Please sign in to comment.