class Post < ActiveRecord::Base
belongs_to :author, :class_name => 'User'
end
class User < ActiveRecord::Base
has_many :posts, :foreign_key => 'author_id'
end
So to build a post for current_user we can do the following:
@post = current_user.posts.build(params[:post])
But what if the @post has to be built using multiple steps like:
@post.author = author
@post.editor = editor
@post.category = category
There are two problems I see with the above:
- It's possible to forget one of the objects and you can have inconsistent data. You can of course use validations to get rid of this problem.
- You need to repeat those steps every time you want to build and save a @post. It also looks brittle in a controller imho.
So would the following make sense
@post = Post.build(params[:post], current_user, editor, category)
i.e define a .build method as follows
class Post < ActiveRecord::Base
def self.build(params, author, editor, category)
post = Post.new(params[:post])
post.author = author
post.editor = editor
post.category = category
post
end
end
This isolates the steps required to build a @post and thus changes can be done in one place (but also update the callers but that's a smaller less error prone change compared to prev case). Also you can write unit tests for .build method.
What do you think?
I've found putting all that assignment logic together in a
build
like method is been good for my code, and for the same reason you mention. I've heard people say that class methods are a code-smell, but I'm yet to see good arguments against this one.