natparkrev国家公园评论网络应用程序

This post showcases the web application I created as part of the curriculum for the Software Engineering program at Flatiron School. This application is an iteration of a simple content management system that implements CRUD (Create, Read, Update, Delete) functionality inside a MVC (Model, View, Controller) design paradigm. This application utilizes the web application library “Sinatra” to facilitate communication between components of the application and the web. Sinatra is built on Rack and provides the convenience of handling HTTP requests and responses. This app also utilizes ActiveRecord in order to provide an interface that allows the application to connect to a database using the relational database management system “SQLite3”. ActiveRecord aids in building database tables, connecting models to database tables and defining relationships between models.

这篇文章展示了我作为Flatiron学校软件工程计划课程的一部分创建的Web应用程序。 此应用程序是简单内容管理系统的迭代,该系统在MVC(模型,视图,控制器)设计范例中实现CRUD(创建,读取,更新,删除)功能。 该应用程序利用Web应用程序库“ Sinatra”来促进应用程序组件与Web之间的通信。 Sinatra基于Rack构建,并提供了处理HTTP请求和响应的便利。 该应用程序还利用ActiveRecord来提供一个界面,该界面允许应用程序使用关系数据库管理系统“ SQLite3”连接到数据库。 ActiveRecord有助于构建数据库表,将模型连接到数据库表以及定义模型之间的关系。

介绍 (Introduction)

The application I built is called “NatParkRev” and its purpose is to provide a place for user-generated reviews of national parks. There are 62 national parks in the United States and no site is available that specifically tracks past and present user reviews for all of those parks. I get a lot of enjoyment visiting national parks so I thought it would be useful to have an application that allows people to read recent reviews of the park they intend on traveling to prior to their visit.

我构建的应用程序称为“ NatParkRev”,其目的是为用户生成的国家公园评论提供场所。 美国有62个国家公园,没有可用网站专门跟踪所有这些公园的过去和现在的用户评论。 访问国家公园给我带来了很多乐趣,因此我认为拥有一个允许人们在访问前阅读打算游览的公园的近期点评的应用程序将非常有用。

Image for post
The main page for NatParkRev. Users are directed to login or sign up to see reviews.
NatParkRev的主页。 引导用户登录或注册以查看评论。

建立 (Setup)

There are ten Ruby gems required to run this application:

要运行此应用程序,需要十个Ruby gem:

gem 'pry' — a runtime development console that allows the developer to freeze code on particular lines.gem 'activerecord', :require => 'active_record' — facilitates the use of objects to be persisted to the database by providing methods and associations.gem 'sinatra' — domain-specific language that handles HTTP requests and responses.gem 'sinatra-activerecord', :require => 'sinatra/activerecord' — provides access to ActiveRecord helper methods and Rake tasks.gem 'sinatra-flash' — provides a way to implement messages that are carried over to the redirected route.gem 'rake'— allows common tasks to be created and run in the terminal.gem 'shotgun'— provides automatic reloading of the rackup config.ru command by running shotgun.gem 'bcrypt'— stores, salts and hashes user passwords.gem 'sqlite3'— database management system.gem 'require_all' — allows for one line to load all files and subdirectories inside a folder.

gem 'pry'运行时开发控制台,允许开发人员在特定行上冻结代码。 gem 'activerecord', :require => 'active_record'通过提供方法和关联来方便使用将对象持久化到数据库中。 gem 'sinatra'处理HTTP请求和响应的特定于域的语言。 gem 'sinatra-activerecord', :require => 'sinatra/activerecord'提供对ActiveRecord助手方法和Rake任务的访问。 gem 'sinatra-flash'提供一种方法来实现传递到重定向路由的消息。 gem 'rake'允许创建常见任务并在终端中运行。 gem 'shotgun' -提供的自动载rackup config.ru通过运行命令shotgungem 'bcrypt'存储,添加盐和哈希用户密码。 gem 'sqlite3'数据库管理系统。 gem 'require_all'允许一行加载文件夹中的所有文件和子目录。

A Rakefile was created to manage tasks during development. In this file, the environment.rb file is loaded and the sinatra/activerecord/rake library is loaded to provide access to many useful rake tasks, including: db:create_migration, db:migrate, db:drop and db:seed.

创建了一个Rakefile来管理开发期间的任务。 在此文件中,将加载environment.rb文件,并且将加载sinatra/activerecord/rake库,以提供对许多有用的rake任务的访问,包括: db:create_migrationdb:migratedb:dropdb:seed

require './config/environment'
require 'sinatra/activerecord/rake'desc 'starts Pry with loaded environment'
task :console do
Pry.start
end

In order to setup the database, migration tables were created for :posts, :parks, :users, :characteristics, and :post_characteristics. The :post_characteristics table is a join table in which columns post_id and characteristic_id are foreign keys. By using the rake db:create_migration task command, a new file is created with the file name as the class name. These files represent the tables in the database. Each line below the create_table line of code below represents the columns in the database. The :posts table has six columns in it, including two foreign keys for the user and park id’s.

为了设置数据库,为:posts:parks:users:characteristics:post_characteristics创建了迁移表。 :post_characteristics表是一个:post_characteristics表,其中post_idcharacteristic_id列是外键。 通过使用rake db:create_migration任务命令,将以文件名作为类名创建一个新文件。 这些文件代表数据库中的表。 下面代码的create_table行下面的每一行代表数据库中的列。 :posts表中有六列,包括用于userpark ID的两个外键。

Image for post
The migration table files are located in the ‘db/migrate’ directory of the application.
迁移表文件位于应用程序的“ db / migrate”目录中。

After all three migration tables are created, the rake db:migrate task command is run which actually creates the tables in the database.

创建所有三个迁移表后,将运行rake db:migrate task命令,该命令实际上在数据库中创建了表。

A seed file was created in the database directory which loads in data to help aid when building the app. The seed file creates User, Post, Park and Characteristic objects, and associates the objects with each other.

在数据库目录中创建了一个种子文件,该文件会加载数据以帮助构建应用程序。 种子文件创建“用户”,“张贴”,“停放”和“特征”对象,并将这些对象彼此关联。

楷模 (Models)

In order to associate objects with each other, ActiveRecord was used. ActiveRecord is the “M” or “model” part of the MVC paradigm. The model is responsible for the representation and manipulation of data in the application. The model is where the main logic of the application is configured. The controller will typically request objects from the model. The model will then request data from the database.

为了使对象彼此关联,使用了ActiveRecord。 ActiveRecord是MVC范例的“ M”或“模型”部分。 该模型负责应用程序中数据的表示和处理。 该模型是配置应用程序的主要逻辑的地方。 控制器通常会从模型中请求对象。 然后,该模型将从数据库中请求数据。

This application has five models: User, Post, Park, Characteristic, and PostCharacteristic. All models are represented as classes. Each model class inherits from ActiveRecord::Base which provides additional methods for these classes. The model class is where associations are created and validations are determined.

该应用程序具有五个模型:用户模型,发布模型,停放模型,特征模型和后特征模型。 所有模型都表示为类。 每个模型类都继承自ActiveRecord::Base ,后者为这些类提供了其他方法。 在模型类中创建关联并确定验证。

Users are associated with the other models as follows: 1. A User has many posts.2. A User has many parks through posts.

用户与其他模型的关联如下:1.一个用户有很多帖子; 2。 用户通过帖子有很多公园。

Posts are associated with the other models as follows:1. A Post belongs to a user.2. A Post belongs to a park.3. A Post has many post characteristics.4. A Post has many characteristics through post characteristics.

帖子与其他模型的关联如下:1。 帖子属于用户2。 邮局属于公园3。 帖子具有很多帖子特征4。 通过帖子特征,帖子具有许多特征。

Parks are associated with the other models as follows:1. A Park has many posts.2. A Park has many users through posts.

公园与其他模型的关联如下:1。 一个公园有很多职位2。 一个公园通过帖子吸引了很多用户。

Characteristics are associated with the other models as follows:1. A Characteristic has many post characteristics.2. A Characteristic has many posts through post characteristics.

特征与其他模型的相关性如下:1。 特征具有很多后期特征2。 特征通过帖子特征具有许多帖子。

PostCharacteristics are associated with the other models as follows:1. A PostCharacteristic belongs to a post.2. A PostCharacteristic belongs to a characteristic.

后特性与其他模型关联如下:1.。 后特性属于职位2。 后特性属于特征。

A User is validated by the presence of the name, email and username attributes, in addition to the uniqueness of the user’s username. The has_secure_password macro is called which provides additional methods for validation, and include #authenticate, #password and #password=. This macro not only requires the presence of a password, but will authenticate the password against a password that is saved in the database which has been salted and hashed by bcrypt.

除了用户名的唯一性之外,还通过名称,电子邮件和用户名属性的存在来验证用户。 所述has_secure_password宏被调用,其提供了一种用于验证附加的方法,并且包括#authenticate#password#password= 。 该宏不仅需要密码,而且还会根据保存在数据库中的密码对密码进行身份验证,该密码已被bcrypt加密和散列。

Image for post
The User model class inherits from ActiveRecord::Base and includes presence validations for all columns in the :users database table.
User模型类继承自ActiveRecord :: Base,并包括:users数据库表中所有列的状态验证。

There are two methods in the User model class. The first is the instance method #slug which transforms the username of an instance of User to a slugged version which yields a string of all lower case letters with hyphens inserted where there were once spaces. The second method is a class method .find_by_slug which iterates over all of the User instances and finds where the slugged username is equivalent to the slugged name that is being searched for. This method is useful when a user of the app is requesting a dynamic route that leads to /users/:username.

User模型类中有两种方法。 第一个是实例方法#slug ,它将User实例的用户名转换为#slug版本,该版本会产生所有小写字母的字符串,并在其中有空格的地方插入连字符。 第二种方法是类方法.find_by_slug ,该方法遍历所有User实例,并找到所键入的用户名与正在搜索的所键入的名称等效的位置。 当应用程序的用户正在请求通往/users/:username的动态路由时,此方法很有用。

观看次数 (Views)

The “V” or “view” part of the MVC paradigm is the user-facing portion of the application. This is what the user sees and interacts with as they navigate the app. There are three subdirectories within the views folder, which are: /parks, /posts and /users.

MVC范例的“ V”或“视图”部分是应用程序的面向用户的部分。 这是用户在浏览应用程序时看到并与之交互的内容。 views文件夹中有三个子目录: /parks/posts/users

The main review page is located in the /posts subdirectory with a filename of index.erb. Views are written as .erb files which consist of HTML and embedded Ruby code. The main review page is the view where all user-generated reviews are displayed to the user of the application. It is important to note that while you do not have to be logged in to view this page, you are required to be logged-in in order to read the actual review.

主审阅页面位于/posts子目录中,文件index.erb 。 视图被编写为.erb文件,该文件由HTML和嵌入式Ruby代码组成。 主审阅页面是一个视图,其中所有用户生成的审阅都显示给应用程序的用户。 重要的是要注意,虽然您不必登录才能查看此页面,但是您必须先登录才能阅读实际的评论。

Two drop down menus are displayed on this page which allows the user to filter reviews by a specific national park or state. Embedded Ruby code is denoted by the substitution tag, <%= and scripting tag, <%. The <select> html tag is utilized to create drop-down menus. The filter by park <select> form iterates over the @parks array, which is an array of all Park instances, Park.all. Each iteration will create an option with that specific park’s route as the value. Each iteration, aptly named park, gets the #slug method called on it which provides a streamlined route name. The drop-down menu display for each option is the park name plus the number of posts associated with that park. An unless statement is included so that if there are no posts with that park, the number of posts will not be displayed so it is easy for the user to discern which parks have reviews and which do not.

此页面上显示两个下拉菜单,允许用户过滤特定国家公园或州的评论。 嵌入式Ruby代码由替换标记<%=和脚本标记<%<select> html标记用于创建下拉菜单。 park <select>表单的过滤器在@parks数组上进行迭代,该数组是所有Park实例Park.all的数组。 每次迭代都会创建一个选项,以该特定公园的路线作为值。 每次迭代(恰当地命名为park )都会调用#slug方法,该方法可提供简化的路线名称。 每个选项的下拉菜单显示为公园名称以及与该公园关联的帖子数。 包括unless声明,以便如果该公园没有帖子,则不会显示帖子的数量,因此用户可以轻松辨别哪些公园有评论,哪些没有评论。

Image for post
Users are able to filter reviews by park using a drop-down list that was created using the <select> tag.
用户可以使用使用<select>标签创建的下拉列表按公园过滤评论。

The main review page also displays the actual table of every review in the database. This table iterates over the @posts array, which is an array of all created Post objects, Post.all. The posts are ordered by the datetime they were updated, in descending order, so that the most recent reviews are displayed at the top of the table. Each iteration creates a table row with various table data cells. Getter methods are called on each post which exposes and displays the necessary information.

主评论页面还显示数据库中每个评论的实际表。 该表遍历@posts数组,该数组是所有已创建的Post对象Post.all 。 这些帖子按它们的更新datetime时间降序排列,以便最新评论显示在表格顶部。 每次迭代都会创建一个包含各种表格数据单元的表格行。 每个post调用Getter方法,以公开和显示必要的信息。

Image for post
The table displaying the list of reviews is populated by iterating over the @posts array.
显示评论列表的表通过迭代@posts数组来填充。

Another important view page is posts/new.erb. This file holds the form for creating a new review. Users are required to fill in all fields on the form which include a title, national park, content and rating. There is also an optional checkbox field for characteristics. Since a timestamps column was included when creating the database table, the created_at and updated_at attribute is automatically populated when a new review is saved to the database. The content field uses the textarea html tag so that a multi-line text field is displayed. The name and value attributes will be available to the developer when the form is submitted via the params hash. The contents of the hash can be manipulated in various ways using nested hashes and arrays.

另一个重要的视图页面是posts/new.erb 。 该文件包含用于创建新评论的表格。 要求用户填写表格上的所有字段,包括标题,国家公园,内容和等级。 还有一个用于特性的可选复选框字段。 由于创建数据库表时包括timestamps列,因此将新评论保存到数据库时,将自动填充created_atupdated_at属性。 内容字段使用textarea html标记,以便显示多行文本字段。 通过params哈希提交表单时,开发人员可以使用name和value属性。 哈希的内容可以使用嵌套的哈希和数组以各种方式进行操作。

Image for post
The new.erb file which displays the form for creating a new review.
new.erb文件,显示用于创建新审阅的表单。

By setting name="post[content]" and not setting the value (since the user will enter in the value), the params hash will be a hash with “post” as the key, along with a nested hash with a key of “content”. This allows the developer to gain access to all of these key/value pairs and use mass assignment when transforming this data into objects later on in the controllers.

通过设置name="post[content]"而不设置值(因为用户将输入值), params哈希将是一个以“ post”为键的哈希值,以及一个嵌套键为“内容”。 这样,开发人员就可以访问所有这些键/值对,并在以后将这些数据转换为对象时在控制器中使用批量分配。

Image for post
An example of what the “params” hash looks like when a user hits the submit button.
用户单击“提交”按钮时“ params”哈希的外观示例。

The users/login.erb view displays a form to the user for when they want to log in to the application. This is a POST request as the user will be sending information back to the server. The username and password are requested of the user and this information is then validated once this request is received by the appropriate route and controller.

users/login.erb视图向用户显示表单,以供用户登录到应用程序时使用。 这是一个POST请求,因为用户将信息发送回服务器。 向username请求usernamepassword ,然后在适当的路由和控制器收到此请求后,便会验证此信息。

Image for post
A simple user login form with required fields of “username” and “password”.
一个简单的用户登录表单,其中包含必填字段“用户名”和“密码”。

控制器 (Controllers)

Controllers are responsible for orchestrating the connection between the browser and the application. They are essentially conductors in an orchestra. Controllers receive requests from the client and routes the requests to the appropriate action. The controller then requests the data from the model, which in turn pulls data from the database. Once the models receive the data, the data is manipulated and sent back to the controller as objects. The controller then sends the objects to the view for rendering. The view will render the HTML which will be to the client as a response by the controller.

控制器负责协调浏览器和应用程序之间的连接。 他们本质上是乐队的指挥。 控制器从客户端接收请求,并将请求路由到适当的操作。 然后,控制器从模型中请求数据,该模型又从数据库中提取数据。 一旦模型接收到数据,就将数据作为对象进行操作并发送回控制器。 然后,控制器将对象发送到视图以进行渲染。 该视图将呈现HTML,该HTML将作为控制器的响应发送给客户端。

There are four controllers in this application: ApplicationController, ParksController, PostsController and UsersController.

此应用程序中有四个控制器:ApplicationController,ParksController,PostsController和UsersController。

The ApplicationController inherits from Sinatra::Base. All other controllers inherit from the ApplicationController which allows all controllers to have access to everything that ApplicationController possesses, including Sinatra::Base. The ApplicationController configures settings which control the features that get enabled. Cookie-based :sessions is enabled to allow users to stay logged into the application without re-entering credentials on every new page that’s loaded. The :views and :public_folder are set to designate specific directories for the location of the view and css/image files.

ApplicationController继承自Sinatra::Base 。 所有其他控制器都继承自ApplicationController,后者允许所有控制器访问ApplicationController拥有的所有内容,包括Sinatra::Base 。 ApplicationController配置用于控制启用功能的设置。 基于Cookie的:sessions已启用,以允许用户保持登录到应用程序的状态,而无需在加载的每个新页面上重新输入凭据。 :views:public_folder设置为视图和CSS /图像文件的位置指定特定目录。

Image for post
The ApplicationController configures settings and inherits from Sinatra::Base.
ApplicationController配置设置并从Sinatra :: Base继承。

The ApplicationController also has helper methods defined to help the other controllers function properly and more efficiently. These include #logged_in?, #current_user, #redirect_if_not_logged_in, #redirect_if_not_post_owner, and #authenticate_and_change_password.

ApplicationController还定义了帮助程序方法,以帮助其他控制器正常且更有效地运行。 这些包括#logged_in?#current_user#redirect_if_not_logged_in#redirect_if_not_post_owner#authenticate_and_change_password

The #authenticate_and_change_password method allows a user to change their account information and utilizes the #authenticate method. The #authenticate method is provided by ActiveRecord::Base and is made available by calling the has_secure_password macro in the User model. When #authenticate is called on a particular instance of User, the password that is passed in (from the user’s input when the login form is submitted) is salted, hashed, and then compared to the salted and hashed password that is stored in the database. If the two version match each other, the return value will be that instance of User. If they do not match, then the return value will be false. At no point is the user’s password ever revealed since the password_digest column name in the users database table is encrypted with bcrypt.

#authenticate_and_change_password方法允许用户更改其帐户信息并使用#authenticate方法。 #authenticate方法由ActiveRecord::Base提供,通过在用户模型中调用has_secure_password宏使其可用。 当在特定的User实例上调用#authenticate ,传入的密码(提交登录表单时从用户输入中传入)将被加密,散列,然后与存储在数据库中的加密散列密码进行比较。 如果两个版本彼此匹配,则返回值将是User该实例。 如果它们不匹配,则返回值将为false。 由于使用bcrypt加密了users数据库表中的password_digest列名,因此永远不会泄露用户的密码。

Image for post
The #authenticate_and_change_password method is called when a user submits a patch request to update their account information.
当用户提交补丁请求以更新其帐户信息时,将调用#authenticate_and_change_password方法。

The PostsController is responsible for all requests pertaining to posts (reviews). When a new review is created, the post '/posts' route is called to action. This route will:

PostsController负责与帖子(评论)有关的所有请求。 创建新评论时,将调用post '/posts'路线以采取行动。 该路线将:

  1. Confirm that the user is logged in.

    确认用户已登录。
  2. Create a new instance of Post by passing in the params hash with the key of :post.

    通过使用:post键传递params哈希来创建Post的新实例。

  3. Assign and associate the new post’s user to the current user.

    分配新帖子的用户并将其关联到当前用户。
  4. Save the newly created post and redirect if the post successfully saves.

    保存新创建的帖子,如果帖子成功保存,则重定向。
Image for post
The post ‘/posts’ route logic will save a new review to the database if certain conditions are met.
如果满足某些条件,则“ / posts”路线逻辑会将新的评论保存到数据库中。

An example of a get request is the get '/posts/:id/edit' route. This route is responsible for displaying the edit form to the user and will:

获取请求的一个示例是get '/posts/:id/edit'路由。 此路线负责向用户显示编辑表单,并将:

  1. Confirm that the user is logged in.

    确认用户已登录。
  2. Find the particular post that is being requested to be edited by searching for the :id attribute in the database that corresponds to the params hash :id that is part of the dynamic url route.

    通过在数据库中搜索对应于params hash :id:id属性,查找要编辑的特定帖子,该参数是动态url路由的一部分。

  3. Confirm that the current user is associated as the owner of the post.

    确认当前用户已关联为帖子的所有者。
  4. Render the posts/edit view.

    渲染posts/edit视图。

Image for post
The get ‘/posts/:id/edit’ route will render an edit review form if certain conditions are met.
如果满足某些条件,则get'/ posts /:id / edit'路由将呈现一个编辑审阅表单。

Once the edit form is filled out correctly, the user can submit the form. The action of the form designates which route is requested. The edit form will send a POST request to the controller, BUT in actuality this is a patch request. A “hidden” input field is created inside the <form> tag of the edit view which designates this request as a patch request instead of a traditional POST request.

正确填写编辑表单后,用户即可提交表单。 表单的动作指定了请求的路线。 编辑表单将向控制器发送一个POST请求,但实际上这是一个patch请求。 在编辑视图的<form>标记内创建一个“隐藏”输入字段,该字段将该请求指定为patch请求,而不是传统的POST请求。

Image for post
A “hidden” input field changes this POST request to a patch request.
“隐藏”输入字段将此POST请求更改为补丁请求。

The associated patch '/posts/:id dynamic route is called to action which will:

关联的patch '/posts/:id动态路由被调用来执行以下操作:

  1. Confirm that the user is logged in.

    确认用户已登录。
  2. Find the particular post that is being requested to be edited by searching for the :id attribute in the database that corresponds to the params hash :id that is part of the dynamic url route.

    通过在数据库中搜索对应于params hash :id:id属性,查找要编辑的特定帖子,该参数是动态url路由的一部分。

  3. Confirm that the current user is associated as the owner of the post.

    确认当前用户已关联为帖子的所有者。
  4. Redirect to the /posts/:id route if the updated post saves in the database.

    如果更新的帖子保存在数据库中,请重定向到/posts/:id路由。

Image for post
The “patch” request responsible for updating the database with changes the user made.
“补丁”请求负责使用用户所做的更改来更新数据库。

The UsersController is responsible for all routes pertaining to user actions. One useful route is the get '/users/:username' dynamic route which is a GET request to a particular user page. This route will:

UsersController负责与用户操作有关的所有路由。 一种有用的路由是get '/users/:username'动态路由,它是对特定用户页面的GET请求。 该路线将:

  1. Confirm that the user is logged in.

    确认用户已登录。
  2. Find the particular user instance in the database via the dynamic :username url. The class method .find_by_slug is utilized here which iterates through the User.all array and searches for where the user’s username converted to slug form matches the passed in slug form of the username (which is pulled from the params hash).

    通过动态:username URL在数据库中找到特定的用户实例。 这里使用类方法.find_by_slug遍历User.all数组,并搜索转换为slug格式的用户名与传入的slug形式的用户名(从params哈希中提取)相匹配。

  3. Render the /users/show page only if the user is found and the user’s username is equivalent to the session’s username.

    仅在找到用户并且用户名与会话的用户名等效时,才渲染/users/show页面。

Image for post
The get request for a users dynamic route.
用户动态路由的get请求。

The post '/login' route utilizes the #authenticate method and will:

post '/login'路由使用#authenticate方法,并将:

  1. Find the User instance by searching the database for username that the user entered in the form.

    通过在数据库中搜索用户在表单中输入的用户名,找到User实例。

  2. Confirm that the user instance exists and that the password entered into the form matches the password in the database.

    确认用户实例存在,并且输入到表单中的密码与数据库中的密码匹配。
  3. Set the :username key of the session hash to that particular user’s username.

    将会话哈希的:username密钥设置为该特定用户的username

  4. Redirect to the previously sought after URL if one was set, or redirect to the user’s page if conditions are met.

    如果设置了URL,则重定向到先前寻求的URL,如果满足条件,则重定向到用户页面。
Image for post
The post ‘login’ route ensures user’s are authenticated in the database before logging them in.
发布“登录”路由可确保在用户登录之前已在数据库中对用户进行身份验证。

最终产品 (The Final Product)

CSS was implemented after coding the backend of the application. The layout.erb file holds the template HTML. A navigation bar was implemented so that only relevant options are displayed to the user, depending on if they are logged in or not. Flash messages were integrated into the controllers to provide the user with useful information when navigating the site. The navigation bar and flash message logic are found in the layout.erb file.

CSS是在对应用程序的后端进行编码之后实现的。 layout.erb文件包含模板HTML。 实施了导航栏,以便根据是否登录,仅向用户显示相关选项。 Flash消息已集成到控制器中,以便在导航站点时为用户提供有用的信息。 导航栏和Flash消息逻辑可在layout.erb文件中找到。

Image for post
The flash message will display various messages to the user depending on the conditions met in the controller routes.
刷新消息将根据控制器路由中满足的条件向用户显示各种消息。
Image for post
Using substitution tags in the layout file to have a dynamic navigation bar.
在布局文件中使用替换标记具有动态导航栏。

Screen captures of the working application are provided below.

下面提供了正在运行的应用程序的屏幕截图。

Image for post
The main page for NatParkRev. Users are directed to login or sign up to see reviews.
NatParkRev的主页。 引导用户登录或注册以查看评论。
Image for post
Users are required to have an account in order to see reviews.
用户必须具有一个帐户才能查看评论。
Image for post
The main review page which shows all reviews in the database.
主评论页面,显示数据库中的所有评论。
Image for post
Users are capable of changing their account information.
用户可以更改其帐户信息。
Image for post
An individual review page. If the logged-in user created the review, buttons are displayed to Edit and Delete.
单个评论页面。 如果登录用户创建了审阅,则将显示按钮以进行编辑和删除。
Image for post
Filtering reviews by the state of Washington.
筛选华盛顿州的评论。
Image for post
“My Page” which shows all reviews that the logged-in user has made.
“我的页面”,显示登录用户已进行的所有评论。
Image for post
A user-friendly interface for creating reviews.
用户友好的界面,用于创建评论。

The Github repository for this application can be found here:https://github.com/dougschallmoser/nat-park-rev-sinatra-app

可以在以下位置找到此应用程序的Github存储库: https : //github.com/dougschallmoser/nat-park-rev-sinatra-app

翻译自: https://medium.com/@dougschallmoser/natparkrev-a-web-application-for-national-park-reviews-300b0e296939

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值