Rails: 通过模型中添加Vitrual Attribute精简控制层代码

来源:互联网 发布:sql tools 编辑:程序博客网 时间:2024/06/16 22:37

最近在看Rails Best Practices网站上的文章,虽然文章发布的时间比较久远(最后一篇是4年前发布的),但里面仍然有大把干货,打算把他们逐个过一遍,顺道会在这里翻译记录一下,有兴趣的同学可以持续关注哈。

坏味道的代码

视图层
<% form_for @user do |f| %>  <%= text_field_tag :full_name %><% end %>
控制器层
class UsersController < ApplicationController  def create    @user = User.new(params[:user])    @user.first_name = params([:full_name]).split(' ', 2).first    @user.last_name = params([:full_name]).split(' ', 2).last    @user.save  endend

上面代码实现的功能是从视图中的表单提交一个full_name字段,在控制层中再手动把它分成first_namelast_name两部分最后再保存到user模型中。

重构

但是给Model赋值并不应该是Contoller的职责,正确的做法应该是在Model一层来实现这个功能。

模型层
class User < ActiveRecord::Base  def full_name    [first_name, last_name]. compact.join(" ").strip  end  def full_name=(name)    split = name.split(' ', 2)    self.first_name = split.first    self.last_name = split.last  endend
视图层
<% form_for @user do |f| %>  <%= f.text_field :full_name %><% end %>
控制层
class UsersController < ApplicationController  def create    @user = User.create(params[:user])  endend

视图层依然没有,变化最大的是模型层和控制层,模型中通过添加一个虚拟的属性full_name=,来为first_namelast_name赋值,如此一来,我们可以直接像create传入带full_name字段的参数,复杂的数据相关逻辑全部丢给了Model来做。

上面的做法其实是要达到一种「fat model, skinny controller」 的效果,除了通过添加虚拟属性的方式之外,还可以借助attr_accesstor+callback的方式来实现这一效果,如下代码

控制层
class User < ActiveRecord::Base  attr_accessor  :full_name  before_save : split_full_name  private  def split_full_name    self.first_name, self.last_name = full_name.splite(" ")  endend
0 0
原创粉丝点击