代码改变世界

Revel示例 - Booking

2013-01-18 09:50  Danny.tian  阅读(4056)  评论(1编辑  收藏  举报

预约示例展示了如下的使用方法:

  • 通过配置Revel的DB module来使用一个SQL数据库
  • 使用GORP "ORM"类库
  • 通过拦截器来检查用户是否登录
  • 使用validation显示行内错误信息

下面是应用程序的内容

booking/app/
    models           # Structs and validation.
        booking.go
        hotel.go
        user.go

    controllers
        init.go    # Register all of the interceptors.
        gorp.go    # A plugin for setting up Gorp, creating tables, and managing transactions.
        app.go     # "Login" and "Register new user" pages
        hotels.go  # Hotel searching and booking

    views
        ...

安装 

这个应用程序使用go-sqlite3, 它包装了C库. 为OSX安装:

  1. 安装Homebrew ( http://mxcl.github.com/homebrew/ )
ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go)

  2. 安装pkg-config 和 sqlite3:

brew install pkgconfig sqlite3

当你完成了SQLite的安装后,我们可以开始运行预约系统了,如下:

$ revel run github.com/robfig/revel/samples/booking

 数据库/Gorp 插件

 app/controllers/gorp.go 定义了GorpPlugin,它负责以下几件事情:

  • OnAppStart: 使用DB module打开一个SQLite的内存数据库并创建User表,Booking表和Hotel表,同时插入一些测试数据.
  • BeforeRequest: 开始一个事务并在controller保存这个事务
  • AfterRequest: 提交事务.如果有error则产生一个Panic.
  • OnException: 回滚事务.

拦截器

app/controllers/init.go 注册一个在每一个action运行前的拦截器:

func init() {
    rev.RegisterPlugin(GorpPlugin{})
    rev.InterceptMethod((*GorpController).Begin, rev.BEFORE)
    rev.InterceptMethod(Application.AddUser, rev.BEFORE)
    rev.InterceptMethod(Hotels.checkUser, rev.BEFORE)
    rev.InterceptMethod((*GorpController).Commit, rev.AFTER)
    rev.InterceptMethod((*GorpController).Rollback, rev.FINALLY)
}

下面是一个示例, 如果用户还没有登录成功,checkUser 在section中查找username并重定向用户到登录页面.

func (c Hotels) checkUser() rev.Result {
    if user := c.connected(); user == nil {
        c.Flash.Error("Please log in first")
        return c.Redirect(Application.Index)
    }
    return nil
}

验证

预约应用程序有很多的验证,请看如下示例:

func (booking Booking) Validate(v *rev.Validation) {
    v.Required(booking.User)
    v.Required(booking.Hotel)
    v.Required(booking.CheckInDate)
    v.Required(booking.CheckOutDate)

    v.Match(b.CardNumber, regexp.MustCompile(`\d{16}`)).
        Message("Credit card number must be numeric and 16 digits")

    v.Check(booking.NameOnCard,
        rev.Required{},
        rev.MinSize{3},
        rev.MaxSize{70},
    )
}

Revel使用验证变量的名字(除非overridden)来应用验证和错误信息记录. 例如,booking.CheckInDate 是必填项,如果Revel评估它为zero date,Revel将在booking.CheckInDate下面存储一个ValidationError到验证上下文。

随后, Hotels/Book.html 模板可以使用field帮助方法,很容易的访问它们:

 {{with $field := field "booking.CheckInDate" .}}
    <p class="{{$field.ErrorClass}}">
      <strong>Check In Date:</strong>
      <input type="text" size="10" name="{{$field.Name}}" class="datepicker" value="{{$field.Flash}}">
      * <span class="error">{{$field.Error}}</span>
    </p>
  {{end}}

field模板帮助函数使用field name作为Key在验证上下文查找错误信息。

 

至此结束。 ----- 已同步到 一步一步学习Revel Web开源框架