- 浏览: 212763 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
liuyanpersonal:
你好啊
单元测试SpringMVC带文件上传的controller -
kkgoing:
teamPhotoController 这个Controlle ...
单元测试SpringMVC带文件上传的controller -
尘枉_yjava:
gwt-ext Out of memory解决办法?? 亲,办 ...
gwt-ext Out of memory解决办法 -
张传龙:
多谢大侠,我找了好久才找到
单元测试SpringMVC带文件上传的controller -
argel_lj:
关键是提示这些信息,而且后面还提示build successf ...
maven经常报Unable to find resource in repository
Are you ready? Let's begin!
Updating Ruby on Rails
When I wrote Part 1, the current version of Rails was 0.9.3. At the time of this writing, Rails is up to version 0.10.0 and has some useful new features. I will use Rails 0.10.0 for this article. If you installed Rails after February 24, 2005, you already have 0.10.0 installed.
Figure 1 shows how to see what RubyGems you have installed (and their version numbers). As with Part 1, I am working on a Windows system, so you will need to translate if you use a different platform.
Figure 1. Listing installed RubyGems
Open a command window and run the command:
gem list --local
Tip: the command gem list --remote
will show all the available RubyGems on the remote gem server on rubyforge.org.
If you don't have Rails 0.10.0 (or later) installed, then you will need to rerun the command:
gem install rails
MySQL security update
In Part 1, I recommended that you leave the MySQL root password blank because (at the time of writing) Rails did not support MySQL's new password protocol. Many of you were not happy with this state of affairs, and to make matters worse, there is now a virus that exploits password vulnerabilities in MySQL on Windows.
Happily, starting with version 0.9.4, Rails now supports the new password protocol.
New scaffold feature
Rails has a new scaffold feature, which I won't explore here, but it's cool enough that I want to make sure you know about it. This is best illustrated by an example.
Part 1 showed how to create a recipe model and controller with the commands:
ruby script\generate model Recipe
ruby script\generate controller Recipe
I then instantiated the scaffolding by inserting scaffold :recipe
into the RecipeController
class. The resulting CRUD controllers and view templates were created on the fly and are not visible for inspection.
The technique described above still works, but you now have another option. Run the command:
ruby script\generate scaffold Recipe
This generates both the model and the controller, plus it creates scaffold code and view templates for all CRUD operations. This allows you to see the scaffold code and modify it to meet your needs. Be careful using this if you've already created models, controllers, or view templates, as it will overwrite any existing files as it creates the scaffold code.
Completing the Recipe Application
It's time to round out the recipe application a bit. After that I'll present some other features of Rails that I'm sure you'll want to know about.
Remember that I created my cookbook application in the directory c:\rails\cookbook; all paths used in this article assume this base directory. If you chose a different location, please be sure to make the proper adjustments to the application paths you see in this article.
You can also download my cookbook source code for this tutorial in one single zip file. This works with Rails 0.13 and later, so if you're still using an older version, I suggest that you follow the upgrade instructions.
For those of you who are cheating (you know who you are) and plan to just download my source code without going through Part 1, you will also need to create a database named cookbook
in MySQL and populate it using cookbook.sql.
Creating a new recipe with a category
Because the code still relies on the scaffolding to create new recipes, there is no way to assign a category to a recipe. This wouldn't be so bad--except that the page created to list all recipes assumes that every recipe will have a category, and it generates an error if this is not true. That means that in the way I left things in Part 1, if you add a new recipe, you'll receive errors while trying to list them.
The fix is to take over the new action from the scaffolding just as I showed already with the edit action. Edit c:\rails\cookbook\app\controllers\recipe_controller.rb and add a new
method like in Figure 2.
Figure 2. The Recipe
controller's new
method
The code @recipe = Recipe.new
creates a new, empty recipe object and assigns it to the instance variable @recipe
. Remember, an instance of the Recipe class represents a row in the recipes
database table. When creating a new recipe object, the Recipe class can assign default values for each field that the view template can use.
The Recipe model class doesn't currently set any such default values, but the view template I'll show off momentarily will use whatever is in the @recipe
object to initialize the display form. Later, you could add default values in the Recipe class that will show up when you create a new recipe.
As with the edit action, this also retrieves a collection of all categories so that it can display a drop-down list of categories from which the user can choose. The @categories
instance variable holds this list of categories.
In the directory c:\rails\cookbook\app\views\recipe, create a file named new.rhtml that contains the HTML template shown below. It's mostly standard HTML, with some extra code to create the <select>
and <option>
tags for the drop-down list of categories:
<html>
<head>
<title>New Recipe</title>
</head>
<body>
<h1>New Recipe</h1>
<form action="/recipe/create" method="post">
<p>
<b>Title</b><br/>
<input id="recipe_title" name="recipe[title]" size="30" type="text" value=""/>
</p>
<p>
<b>Description</b><br/>
<input id="recipe_description" name="recipe[description]"
size="30" type="text" value=""/>
</p>
<p>
<b>Category:</b><br/>
<select name="recipe[category_id]">
<% @categories.each do |category| %>
<option value="<%= category.id %>">
<%= category.name %>
</option>
<% end %>
</select>
</p>
<p>
<b>Instructions</b><br/>
<textarea cols="40" id="recipe_instructions" name="recipe[instructions]"
rows="20" wrap="virtual">
</textarea>
</p>
<input type="submit" value="Create"/>
</form>
<a href="/recipe/list">Back</a>
</body>
</html>
This is not much different from the edit template from Part 1. I left out the recipe's date because I'll set it to the current date when a user posts the form back to the web app. This ensures that the recipe's date will always be its creation date.
If you look at the form tag, you will see that this form will post to a create
action in the recipe
controller. Edit c:\rails\cookbook\app\controllers\recipe_controller.rb and add this create
method:
def create
@recipe = Recipe.new(@params['recipe'])
@recipe.date = Date.today
if @recipe.save
redirect_to :action => 'list'
else
render_action 'new'
end
end
This method first creates a new recipe object and initializes it from the parameters posted by the form in new.rhtml. Then it sets the recipe's date to today's date, and tells the recipe object to save itself to the database. If the save is successful, it redirects to the list action that displays all recipes. If the save fails, it redirects back to the new action so the user can try again.
Give it a try. Start the web server by opening a command window, navigating to c:\rails\cookbook, and running the command ruby script\server
. Then browse to http://127.0.0.1:3000/recipe/new
and add a new recipe like the one shown in Figure 3.
Figure 3. Adding a new recipe with a category
After you create the new recipe, you should see something like Figure 4.
Figure 4. List of all recipes
Deleting a recipe
If you remember from Part 1, once I took over the list action from the scaffolding I no longer had a way to delete a recipe. The list action must implement this. I'm going to add a small delete link after the name of each recipe on the main list page that will delete its associated recipe when clicked. This is easy.
First, edit c:\rails\cookbook\app\views\recipe\list.rhtml and add the delete link by making it look like this:
<html>
<head>
<title>All Recipes</title>
</head>
<body>
<h1>Online Cookbook - All Recipes</h1>
<table border="1">
<tr>
<td width="40%"><p align="center"><i><b>Recipe</b></i></td>
<td width="20%"><p align="center"><i><b>Category</b></i></td>
<td width="20%"><p align="center"><i><b>Date</b></i></td>
</tr>
<% @recipes.each do |recipe| %>
<tr>
<td>
<%= link_to recipe.title,
:action => "show",
:id => recipe.id %>
<font size=-1>
<%= link_to "(delete)",
{:action => "delete", :id => recipe.id},
:confirm => "Really delete #{recipe.title}?" %>
</font>
</td>
<td><%= recipe.category.name %></td>
<td><%= recipe.date %></td>
</tr>
<% end %>
</table>
<p><%= link_to "Create new recipe", :action => "new" %></p>
</body>
</html>
The main change here is the addition of this link:
<%= link_to "(delete)", {:action => "delete", :id
=> recipe.id},
:confirm => "Really delete #{recipe.title}?" %>
This is different from the previous ones. It uses an option that generates a JavaScript confirmation dialog. If the user clicks on OK in this dialog, it follows the link. It takes no action if the user clicks on Cancel.
Try it out by browsing to http://127.0.0.1:3000/recipe/list
. Try to delete the Ice Water recipe, but click on Cancel when the dialog pops up. You should see something like Figure 5.
Figure 5. Confirm deleting the Ice Water recipe
Now try it again, but this time click on OK. Did you see the results shown in Figure 6?
Figure 6. Error deleting the Ice Water recipe
Alright, I admit it; I did this on purpose to remind you that it's OK to make mistakes. I added a link to a delete action in the view template, but never created a delete action in the recipe controller.
Edit c:\rails\cookbook\app\controllers\recipe_controller.rb and add this delete
method:
def delete
Recipe.find(@params['id']).destroy
redirect_to :action => 'list'
end
The first line of this method finds the recipe with the ID from the link, then calls the destroy method on that recipe. The second line merely redirects back to the list action.
Try it again. Browse to http://127.0.0.1:3000/recipe/list
and try to delete the Ice Water recipe. Now it should look like Figure 7, and the Ice Water recipe should be gone.
Figure 7. Ice Water recipe is gone
Using layouts
Part 1 used Rails' scaffolding to provide the full range of CRUD operations for categories, but I didn't have to create any links from our main recipe list page. Instead of just throwing in a link on the recipe list page, I want to do something more generally useful: create a set of useful links that will appear at the bottom of every page. Rails has a feature called layouts, which is designed just for things like this.
Most web sites that have common headers and footers across all of the pages do so by having each page "include" special header and footer text. Rails layouts reverse this pattern by having the layout file "include" the page content. This is easier to see than to describe.
Edit c:\rails\cookbook\app\controllers\recipe_controller.rb and add the layout
line immediately after the class definition, as shown in Figure 8.
Figure 8. Adding a layout to the recipe controller
This tells the recipe controller to use the file standard-layout.rhtml as the layout for all pages rendered by the recipe controller. Rails will look for this file using the path c:\rails\cookbook\app\views\layouts\standard-layout.rhtml, but you will have to create the layouts directory because it doesn't yet exist. Create this layout file with the following contents:
<html>
<head>
<title>Online Cookbook</title>
</head>
<body>
<h1>Online Cookbook</h1>
<%= @content_for_layout %>
<p>
<%= link_to "Create new recipe",
:controller => "recipe",
:action => "new" %>
<%= link_to "Show all recipes",
:controller => "recipe",
:action => "list" %>
<%= link_to "Show all categories",
:controller => "category",
:action => "list" %>
</p>
</body>
</html>
Only one thing makes this different from any of the other view templates created so far--the line:
<%= @content_for_layout %>
This is the location at which to insert the content rendered by each recipe action into the layout template. Also, notice that I have used links that specify both the controller and the action. (Before, the controller defaulted to the currently executing controller.) This was necessary for the link to the category list page, but I could have used the short form on the other two links.
Before you try this out, you must perform one more step. The previous recipe view templates contain some HTML tags that are now in the layout, so edit c:\rails\cookbook\app\views\recipe\list.rhtml and delete the extraneous lines at the beginning and end to make it look like this:
<table border="1">
<tr>
<td width="40%"><p align="center"><i><b>Recipe</b></i></td>
<td width="20%"><p align="center"><i><b>Category</b></i></td>
<td width="20%"><p align="center"><i><b>Date</b></i></td>
</tr>
<% @recipes.each do |recipe| %>
<tr>
<td>
<%= link_to recipe.title,
:action => "show",
:id => recipe.id %>
<font size=-1>
<%= link_to "(delete)",
{:action => "delete", :id => recipe.id},
:confirm => "Really delete #{recipe.title}?" %>
</font>
</td>
<td><%= recipe.category.name %></td>
<td><%= recipe.date %></td>
</tr>
<% end %>
</table>
Similarly, edit both c:\rails\cookbook\app\views\recipe\edit.rhtml and c:\rails\cookbook\app\views\recipe\new.rhtml to delete the same extraneous lines. Only the form tags and everything in between should remain.
Browse to http://127.0.0.1:3000/recipe/list
, and it should look like Figure 9.
Figure 9. Using a layout with common links
The three links at the bottom of the page should now appear on every page displayed by the recipe controller. Go ahead and try it out!
If you clicked on the "Show all categories" link, you probably noticed that these nice new links did not appear. That is because the category pages display through the category controller, and only the recipe controller knows to use the new layout.
To fix that, edit c:\rails\cookbook\app\controllers\category_controller.rb and add the layout
line as shown in Figure 10.
Figure 10. Adding a layout to the category controller
Now you should see the common links at the bottom of all pages of the recipe web application.
Showing recipes in a category
The final task is to add the ability to display only those recipes in a particular category. I'll take the category displayed with each recipe on the main page and turn it into a link that will display only the recipes in that category.
To do this, I'll change the recipe list view template to accept a URL parameter that specifies what category to display, or all categories if the user has omitted the parameter. First, I need to change the list
action method to retrieve this parameter for use by the view template.
Edit c:\rails\cookbook\app\controllers\recipe_controller.rb and modify the list
method to look like this:
def list
@category = @params['category']
@recipes = Recipe.find_all
end
Then edit c:\rails\cookbook\app\views\recipe\list.rhtml to look like this:
<table border="1">
<tr>
<td width="40%"><p align="center"><i><b>Recipe</b></i></td>
<td width="20%"><p align="center"><i><b>Category</b></i></td>
<td width="20%"><p align="center"><i><b>Date</b></i></td>
</tr>
<% @recipes.each do |recipe| %>
<% if (@category == nil) || (@category == recipe.category.name)%>
<tr>
<td>
<%= link_to recipe.title,
:action => "show",
:id => recipe.id %>
<font size=-1>
<%= link_to "(delete)",
{:action => "delete", :id => recipe.id},
:confirm => "Really delete #{recipe.title}?" %>
</font>
</td>
<td>
<%= link_to recipe.category.name,
:action => "list",
:category => "#{recipe.category.name}" %>
</td>
<td><%= recipe.date %></td>
</tr>
<% end %>
<% end %>
</table>
There are two changes in here that do all the work. First, this line:
<% if (@category == nil) || (@category == recipe.category.name)%>
decides whether to display the current recipe in the loop. If the category is nil
(there was no category parameter on the URL), or if the category from the URL parameter matches the current recipe's category, it displays that recipe.
Second, this line:
<%= link_to recipe.category.name,
:action => "list",
:category => "#{recipe.category.name}" %>
creates a link back to the list action that includes the proper category parameter.
Browse to http://127.0.0.1:3000/recipe/list
and click on one of the Snacks links. It should look like Figure 11.
Figure 11. Showing only snacks
What is it? How long did it take?
That's it! This is a reasonably functional online cookbook application developed in record time. It's a functional skeleton just begging for polish.
Wading through all of the words and screenshots in this article may have obscured (at least somewhat) exactly what this code can do and in what amount of developer time. Let me present some statistics to try to put it all into perspective.
Fortunately, Rails has some built-in facilities to help answer these questions. Open up a command window in the cookbook directory (c:\rails\cookbook) and run the command:
rake stats
Your results should be similar to Figure 12. Note that LOC means "lines of code."
Figure 12. Viewing development statistics
I won't give a detailed description of each number produced, but the last line has the main figure I want to point out:
Code LOC: 47
This says that the actual number of lines of code in this application (not counting comments or test code) is 47. It took me about 30 minutes to create this application! I could not have come even close to this level of productivity in any other web app development framework that I have used.
Maybe you're thinking that this is an isolated experience using an admittedly trivial example. Maybe you're thinking that this might be OK for small stuff, but it could never scale. If you harbor any such doubts, the next section should lay those to rest.
Ruby on Rails Success Stories
Rails is a relatively young framework. As of this writing, it's been barely six months since the first public release. Yet it debuted with such a stunning feature set and solid stability that a vibrant developer community quickly sprang up around it. Within this time frame, several production web applications have been deployed that were built with Ruby on Rails.
相关推荐
【个人博客】 Java、技术面试必备基础知识、Leetcode、计算机操作系统、计算机网络等_CSLearning
yolo系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值
那些年,与你同分同位次的同学都去了哪里?全国各大学在四川2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
人力资源+大数据+薪酬报告+涨薪调薪,在学习、工作生活中,越来越多的事务都会使用到报告,通常情况下,报告的内容含量大、篇幅较长。那么什么样的薪酬报告才是有效的呢?以下是小编精心整理的调薪申请报告,欢迎大家分享。相信老板看到这样的报告,一定会考虑涨薪的哦。
那些年,与你同分同位次的同学都去了哪里?全国各大学在四川2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
这是一个基于全卷积神经网络的语音识别系统_DFCNN-master
一个可以运行在 vercel 上的 go 语言框架,基于 g
基于一维卷积神经网络(1D-CNN)的多元时间序列分类_TSC-CNN
网鼎杯
那些年,与你同分同位次的同学都去了哪里?全国各大学在四川2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
那些年,与你同分同位次的同学都去了哪里?全国各大学在四川2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
那些年,与你同分同位次的同学都去了哪里?全国各大学在四川2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
OrinNX平台JetPack 5.1.4-R35.6.0版本相机相关补丁1
MD5EditTools,MD5修改工具.exe
原文链接:https://blog.csdn.net/zsd12379/article/details/141281454 包含功能: 业主管理:实现业主信息的录入、编辑、查询与删除,确保业主数据的准确性和完整性。 维修员管理:管理维修员的基本信息、工作状态和派工情况,优化维修资源配置。 楼宇信息管理:记录并维护楼宇的基本信息、设施详情及状态,支持快速查询与更新。 业主投诉管理:接收并处理业主的投诉信息,跟踪处理进度,提升业主满意度。 业主报修管理:提供便捷的报修渠道,记录报修详情,实现报修请求的有效管理。 报修处理管理:分配报修任务给维修员,跟踪报修进度,确保报修问题及时解决。 缴费信息管理:管理业主的缴费记录,包括物业费、维修基金等,支持费用查询与提醒。 建议反馈管理:收集业主的建议与反馈,促进物业服务的持续改进和优化。
<项目介绍> - 该项目是为了研究基于深度卷积神经网络的图像去噪算法,是利用DnCNN模型,但是为了比较该算法的效果,另外实现了四种传统的图像去噪算法(均值滤波、中值滤波、非局部均值滤波NLM和三维块匹配滤波BM3D)作为对照组 - 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
2023-04-06-项目笔记-第三百零三阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.301局变量的作用域_301- 2024-10-31
那些年,与你同分同位次的同学都去了哪里?全国各大学在四川2020-2024年各专业最低录取分数及录取位次数据,高考志愿必备参考数据
High_net_worth.dta