跳到主要内容

开始使用Sinatra

这篇文章首次出现在问题239.net杂志 - 世界上最畅销的网页设计师和开发者杂志。

最着名的Ruby on Rails,Ruby很有趣,易于使用,易于理解且易于学习。 Sinatra是一个非常不同的框架,它使用2000行Ruby编写,不强制执行模型 - 视图 - 控制器(MVC)或使用不同的工具,配置文件或脚手架。

Sinatra应用程序通常只包含一个文件,足以完成工作。该框架最适合较小的Web应用程序,但如果大型Web应用程序需要API或Web界面来实现某些辅助功能,那么Sinatra是理想的选择。

开始,确保你安装了Ruby(它预装在大多数现代Mac上)。对于那些之前使用过Ruby的人来说,你会知道它的强大功能是打包的Ruby应用程序库,称为gems。 Sinatra作为宝石安装,所以你也需要确保安装了RubyGems。完成此操作后,打开终端并运行以下命令:

  1. 宝石安装sinatra

这将安装Sinatra并使您能够在Ruby应用程序中访问它。创建文件Hello.rb的包含以下代码:

  1. 要求'sinatra'
  2. 得到'/'做
  3. “你好,世界!”
  4. 结束

首先,需要加载Sinatra框架代码。然后,配置域路由,我们调用得到因为这是我们对域路由感兴趣的HTTP方法/。在此方法中,我们添加“Hello World!”作为加载路径时要返回的文本。回到终端窗口,尝试运行Ruby Hello.rb开始你的Sinatra应用程序。这将使用默认端口加载Web服务器4567。在浏览器中导航到HTTP://本地主机:4567你应该看到,“Hello World!”。 (按按Ctrl + C杀死网络服务器)。

When no to-do items are returned from the database the user is redirected to the add form, which posts to /new to add new items

当没有从数据库返回任何待办事项时,用户被重定向到添加表单,该表单发布到/ New以添加新项目

到底Hello.rb的,添加以下代码:

  1. 得到'/ Hello /:name'做
  2. “你好#{params ['name']}”
  3. 结束

运行ruby hello.rb再次启动Web服务器并导航到HTTP://本地主机:4567 /你好/蒂姆。现在应该在浏览器中返回“Hello Tim”。

在本教程的其余部分中,我们将介绍如何创建一个简单的待办事项列表应用程序。此应用程序将使用SQLite作为数据库,并允许添加,标记为已完成和删除待办事项。第一步是连接数据库。 Sinatra没有附带数据库工具或对象关系映射(ORM),所以再次安装几个宝石。在终端中运行以下命令以安装这些命令:

  1. Gem Install Dm-sqlite-adapter
  2. gem install data_mapper

这安装的DataMapper,这是一个Ruby ORM和DataMapper的SQLite适配器。如果您正在使用MySQL或PostgreSQL等不同的数据库,则可以使用其他适配器。

现在我们可以开始创建应用程序了。为您的应用程序创建一个名为的目录Todo_list。在这里,为Sinatra应用程序启动一个新的Ruby文件Web.rb。使用以下命令启动此文件要求线路:

  1. 要求'sinatra'
  2. 需要'data_mapper'

这条简短的指令将Sinatra和DataMapper添加到应用程序中。在其下,添加以下代码以创建SQLite数据库,表和架构:

  1. DataMapper :: setup(:default,“sqlite3://#{Dir.pwd} /todo_list.db”)
  2. 类项目
  3. 包括DataMapper :: Resource
  4. Property:id,Serial
  5. property:content,Text,:required => true
  6. property:done,Boolean,:required => true,:default => false
  7. Property:created,DateTime
  8. 结束
  9. DataMapper.finalize.auto_upgrade!

首先,此代码调用DataMapper设置以创建SQLite数据库连接 -Todo_list.db。然后定义模型以创建待办事项列表项,其包括ID内容, 一个DONE标记和创建日期。最后一行将完成DataMapper模型Auto_upgrade!创建表并添加新列(如果它们被添加)。

现在我们有了数据库,我们也可以添加一些路由:

  1. 得到'/'做
  2. @items = Item.all(:order =>:created.desc)
  3. 如果@ Items.empty重定向'/ New'?
  4. Erb:index
  5. 结束

像一些早期的例子,创建根路由我们称之为得到路由参数为的方法/。在此内部,使用。在数据库上运行查询项目Class,它是在DataMapper模型中早期生成的。从数据库中,我们请求按创建日期排序的所有项目。然后将其设置为@items变量。如果为空,则将用户重定向到/新Route(我们将很快创建)以防止索引视图加载。

Once to-do items have been added they are listed on the homepage of the application with a button back to the 'Add todo item' form to add further items

一旦添加了待办事项,它们就会在应用程序的主页上列出,并带有一个按钮,返回“添加待办事项”表单以添加更多项目

虽然Sinatra不是严格意义上的MVC,但它确实允许使用视图。这些可以使用许多不同的模板语言。在这个例子中我们正在使用ERB并希望看到Index.erb要加载。默认情况下,视图存储在意见目录。创建目录并创建Index.erb在里面:

  1. <ULid =“todo-list”class =“unstyled”>
  2. <%@ items.each do | item | %>
  3. <id =“<%= item [:id]%>”>
  4. <跨度类=“项目”>
  5. <%= item [:done]? “ #{项[:内容]} 德尔>“:item [:content]%>
  6. 跨度>
  7. <跨度类=“右拉式”>
  8. <一个href =“#”class =“btn done”> <%= item [:done]? “未完成”:“完成”%> 一个>
  9. <一个href =“/ delete / <%= item [:id]%>”class =“btn btn-danger”>删除一个>
  10. 跨度>
  11. 里>
  12. <%end%>
  13. UL>
  14. <一个href =“/ new”class =“btn btn-primary”>添加待办事项一个>

在此视图中,将为内容输出创建基本HTML。该ERB标签允许将Ruby的一些注入到布局中。@ Item.each用于遍历所有待办事项。在其中,使用返回待办事项的不同元素ERB表达标签。

表示完成待办事项,HTML标签被添加到项目内容中,“完成”按钮文本被更改为“未完成”,这样就可以撤消已完成的项目。为了实现这一点,使用三元运算符。这会根据待办事项是否已标记为已完成而创建不同的状态。

我们在这个视图中拥有如此少的HTML的原因是因为大多数都在布局中。 Sinatra使您可以创建一个名为的视图布局- 然后是正在使用的模板语言的扩展 - 在这种情况下,Layout.erb。然后为所有视图加载此文件。

The to-do list items are listed with a done button allowing the item to be marked as done (via Ajax) and a delete button taking the user to a confirmation page

待办事项列表项目列出了完成按钮,允许项目标记为已完成(通过Ajax)和删除按钮将用户带到确认页面

布局必须包含变量,即显示主视图内容的位置。例如:

  1. <HTML>
  2. <>
  3. <标题> Todo List 标题>
  4. 头>
  5. <身体>
  6. <%=产量%>
  7. 身体>
  8. HTML>

满满的Layout.erb用过的可以在GitHub上找到,并使用Twitter Bootstrap构建。

主页路由重定向到/新如果数据库不包含任何待办事项。需要生成此路由:

  1. 得到'/新'做
  2. @title =“添加待办事项”
  3. Erb:新的
  4. 结束
  5. 发布'/ New'做
  6. Item.create(:content => params [:content],:created => Time.now)
  7. 重定向'/'
  8. 结束

这有两个要素:a得到和a岗位。该得到将用于渲染表单以添加新的待办事项,以及岗位将处理来自此表单的发布请求。

渲染表单不需要逻辑。我们设置了一个@标题在...中返回的变量

布局视图的标签,然后我们调用New.erb视图。

帖子需要在数据库中创建待办事项。 DataMapper可以处理所有这些创建方法。我们传入PARAMS [:内容],这是表单中的文本以及使用的时间戳现在的时间。在此之后,重定向完成,返回到将显示新添加的待办事项的主页。

形式在New.erb是一种非常标准的 - 非常基本的 - HTML形式:

  1. <形成action =“/ new”class =“form-inline”method =“POST”>
  2. <输入type =“text”placeholder =“Todo item”name =“content”>
  3. <按键type =“submit”class =“btn”>发布按键>
  4. 形成>

标记和删除项目

既然我们可以在这个列表中添加新项目,它就非常接近功能 - 但我们也希望能够将项目标记为已完成并删除它们。举两个这样做的方法的例子,一个将通过Ajax完成,另一个将具有传统加载的确认页面。

从标记项目完成开始,Ajax请求将需要在某处发布。为此,创建另一个post方法,就像我们为/ New所做的那样。在这种情况下它将是/完成

  1. 发布'/ Done'做
  2. item = Item.first(:id => params [:id])
  3. item.done =!item.done
  4. Item.save
  5. content_type'application / json'
  6. Value = Item.done? '完成':'未完成'
  7. {:id => params [:id],:status => value} .to_json
  8. 结束

在这段代码中,我们使用DataMapper方法从数据库中获取待办事项,基于ID由Ajax调用给出。该DONE然后将数据库中的元素设置为与之前相反的元素:因此,如果它已“完成”,则将其设置为“未完成”;如果是“未完成”,“完成”。这在数据库中表示为Boolean:“true”或“false”。

最后,该项目将保存回数据库。我们现在需要返回使用JavaScript Object Notation(JSON)完成的确认。需要将内容类型标头设置为JSON,并根据数据库中的done元素设置值。

To denote that a to-do item is done, HTML tags are added to the item content and the 'done' button text is changed to 'not done'

+$To denote that a to-do item is done, HTML tags are added to the item content and the 'done' button text is changed to 'not done'

ID都被添加到哈希中,使用哈希转换为JSONTo_json方法。该To_json方法作为JSON Gem的一部分提供。因此,请使用该命令进行安装宝石安装json。它还需要使用语法在文件的顶部需要json

可以将JavaScript添加到文件中Todo_list.js。 JavaScript,CSS和图像等文件类型进入Sinatra的“公共”目录。在查找应用程序中的路由之前,Sinatra会在此处检查文件。 JavaScript文件Todo_list.js然后可以在布局视图中引用。

  1. $(document).ready(function(){
  2. $(“。done”)。click(function(e){
  3. var item_id = $(this).parents('li')。attr('id');
  4. $就({
  5. 类型:“POST”,
  6. Url:“/ Done”,
  7. data:{id:item_id},
  8. 完成(function(data){
  9. if(data.status =='done'){
  10. $(“#”+ data.id +“a.done”)。text('Not done')
  11. $(“#”+ data.id +“.item”)。wrapInner(“ “);
  12. }
  13. 其他{
  14. $(“#”+ data.id +“a.done”)。text('Done')
  15. $(“#”+ data.id +“.item”)。html(function(i,h){
  16. 返回h.replace(“ “,”“);
  17. });
  18. }
  19. });
  20. E.preventDefault();
  21. });
  22. });

JQuery用于此Ajax调用。您会注意到它是一个相当标准的AjaxPOST打电话给/完成路线。待办事项ID是从...获取的

  • 标记并在post请求中作为JSON传递。在完成Ajax调用之后,从Sinatra发回的数据用于更改按钮的名称并添加或删除根据需要从文本中标记。

    每个待办事项的删除按钮链接到/删除,附加项目ID。例如,要删除待办事项一,删除按钮链接到/删除/ 1。代码如下:

    1. 得到'/ Delete /:id'做
    2. @item = Item.first(:id => params [:id])
    3. Erb:删除
    4. 结束
    5. 发布'/ Delete /:id'做
    6. 如果params.has_key?(“ok”)
    7. item = Item.first(:id => params [:id])
    8. Item.destroy
    9. 重定向'/'
    10. 其他
    11. 重定向'/'
    12. 结束
    13. 结束

    代码的第一部分使用了得到方法用:ID用于查找待办事项的参数ID来自网址。然后加载具有匹配id的数据库中的第一项。最后的元素得到方法调用视图Delete.erb

    代码的第二部分是岗位方法,这用作内置删除确认表单的操作Delete.erb。该方法检查是否已按下确定按钮 - 而不是取消按钮 - 然后根据该数据库查找数据库中的第一个待办事项列表项。ID在URL中,并在重定向回主页之前将其销毁。

    The delete button for each to-do item links to /delete, which is appended with the item id

    每个待办事项的删除按钮链接到/删除,后面附有项目ID

    很像New.erbDelete.erb有一个基本的HTML表单,但你会看到它有一个隐藏的价值 -_方法- 执行删除方法。它还返回表单前的待办事项内容,以确认将删除正确的项目。

    例如,要求确认:

    1. <P>您确定要删除: P>
    2. <块引用> <P> <%= @ item.content%> P> 块引用>
    3. <形成action =“/ delete / <%= @ item.id%>”method =“POST”>
    4. <输入name =“_ method”type =“hidden”value =“delete”/>
    5. <按键type =“submit”class =“btn btn-primary”name =“ok”>好的按键>
    6. <按键type =“submit”class =“btn”name =“cancel”>取消按键>
    7. 形成>

    将所有这些组合在一起后,您将拥有一个在Sinatra中构建的完整待办事项列表应用程序。这可以使用命令运行Ruby Web.rb,该应用程序将在HTTP://本地主机:4567

    为了进一步改进此应用程序,可以添加身份验证 - 这将允许用户特定的待办事项列表。这里有一颗宝石西纳特拉认证这将为您完成大部分身份验证。您还可以构建一些额外的验证和错误处理来形成提交。

    另外值得一提的是,本文并未真正讨论过安全问题。Sinatra有机架保护默认情况下启用,这将保护您的应用程序免受常见和机会攻击。

    谢谢康斯坦丁哈斯他的同行评审

    话:蒂姆米尔伍德

    Tim是Acquia的客户顾问和自由网络开发人员,也是Drupal社区的活跃成员。

  • 话题



    翻译字数超限