vba 下拉列表 排序
We’re going to make a simple sort drop down with two options using form_with
, a rails form helper. Before we get started, what exactly is form_with
and why is it useful? Prior to Rails 5.1, we had only form_for
and form_tag
form helpers. form_for
is used to create and update model object attributes, and requires a model be passed in as an argument. A FormBuilder
object is yielded to the variable form
in the below code snippet, which allows us to generate fields associated with the attributes of our review
instance variable:
我们将使用form_with
helper form_with
通过两个选项进行简单排序。 在开始之前, form_with
到底是什么?为什么有用? 在Rails 5.1之前,我们只有form_for
和form_tag
表单助手。 form_for
用于创建和更新模型对象属性,并要求将模型作为参数传递。 下面的代码片段将FormBuilder
对象转换为变量form
,使我们能够生成与review
实例变量的属性相关联的字段:
# /app/views/movies/show.html.erb <%= form_for @review do |form| %>
<%= form.hidden_field :movie_id, value: @movie.id %> <%= form.label :review %>
<%= form.text_area :review %> <%= form.label :rating %>
<%= form.number_field :rating %> <%= form.submit "Add Review" %>
<% end %>
form_tag
on the other hand is for forms where you don’t need to pass in a model object, and doesn’t utilize FormBuilder
field helpers. form_with
is the best of both worlds. It takes the functionalities of both form_for
and form_tag
and combines them. form_with
utilizes FormBuilder
regardless of whether or not a model object is passed in, as you’ll see shortly.
另一方面, form_tag
用于不需要传递模型对象并且不使用FormBuilder
字段帮助器的FormBuilder
。 form_with
是两全其美。 它同时具有form_for
和form_tag
的功能,并将它们组合在一起。 不管您是否传入模型对象, form_with
使用FormBuilder
,您将很快看到。
Now on to our drop down! form_with
accepts the following arguments: model
, scope
, url
, format
, options
, & block
. We’ll be using a url
, an option
, and passing our form a block
to make our sorted drop down. We have a simple Movie app where a user can view a movie’s page, and both see all the reviews and ratings for a movie, as well as add their own. We’ll be implementing a way to order a movie’s reviews based on rating. We already have our database, classes, controllers, views, and routes mapped out and set up. There are three steps that we’ll walk through in order to create a functioning form:
现在开始我们的下拉菜单! form_with
接受以下参数: model
, scope
, url
, format
, options
和block
。 我们将使用一个url
,一个option
,并通过我们的形式的block
,使我们的排序下拉。 我们有一个简单的电影应用程序,用户可以在其中查看电影页面,既可以查看电影的所有评论和评分,也可以添加自己的评论。 我们将实现一种根据等级来订购电影评论的方法。 我们已经有数据库,类,控制器,视图和路由被映射和设置。 我们将通过三个步骤来创建可运行的表单:
Create instance methods in our
Movie
class在
Movie
类中创建实例方法Write out our
form_with
form写出我们的
form_with
表格Perform some additional logic in our
MoviesController
'sshow
method在
MoviesController
的show
方法中执行一些其他逻辑
First, let’s create two instance methods in our Movie
class. One will return an array of a movie’s associated review
instances sorted from high to low based on their ratings, and the other will sort from low to high:
首先,让我们在Movie
类中创建两个实例方法。 一个会返回与电影相关的数组 review
实例根据其评级从高到低排序,另一个实例从低到高排序:
# /app/models/movie.rbdef ratings_low_to_high
self.reviews.sort_by do |review|
review.rating
end
enddef ratings_high_to_low
self.ratings_low_to_high.reverse
end
Next let’s go over to our show.html.erb
file and start building out our form! Form’s by default send post requests, which are used to send data to a server with the intent of creating or updating a resource. We’re not actually updating our movie
instance here, we’re simply reordering some of the data associated with it. Because of that, we need to specify the method with which we want to send the request. In this case we’ll simply be redirecting back to our MoviesController
's show
method with a get request via our movie_path
path helper. Unlike form_for
and form_tag
, form_with
submits its data using an XHR (Ajax)
request by default. We’re not going to be using Ajax in this example, so we can pass form_with
an option of local: true
to adjust this. So far our form looks like this:
接下来,让我们show.html.erb
文件,开始构建表单! 默认情况下,表单发送发送请求,用于将数据发送到服务器,以创建或更新资源。 我们实际上并没有在这里更新movie
实例,我们只是在重新排序与它关联的一些数据。 因此,我们需要指定发送请求的方法。 在这种情况下,我们将通过movie_path
路径帮助器通过get请求将其重定向回MoviesController
的show
方法。 与form_for
和form_tag
不同,默认情况下, form_with
使用XHR (Ajax)
请求提交其数据。 在此示例中,我们将不使用Ajax,因此我们可以通过form_with
的local: true
选项来调整它。 到目前为止,我们的表单如下所示:
# /app/views/movies/show.html.erb<%= form_with(url: movie_path(@movie), method: :get, local: true) do |form| %>
<% end %>
Now that we have the basics set up, it’s time to actually create our drop down. To do this we can use the select
helper on our FormBuilder
object. As with all forms, we need a way to actually send back our selection. When creating an object with form_with
, you use the object’s attributes as keys for the corresponding values submitted via the form. Although we’re not dealing with a model object here, we still need a way to send back our selection. While a key in a form for creating or updating a model instance must correspond to an actual attribute of the model, our key here can be anything. We just need it to identify our selection so we can perform some logic in our MoviesController
's show
method, and send back the correctly sorted data. For this example, we’ll name the key :order
. The second argument is just what we want our options to be, in our case “Ratings High to Low”
, and “Ratings Low to High”
. All we need to do to complete our form now is to use the submit
helper to actually place our request. We can pass an optional argument if we want our button to say something other than the default save
. We’ll go ahead and change that to “Submit”
, which gives us the completed form below:
现在我们已经建立了基础,是时候实际创建下拉列表了。 为此,我们可以在FormBuilder
对象上使用select
帮助器。 与所有表格一样,我们需要一种方法来实际发回我们的选择。 使用form_with
创建对象时,可以将对象的属性用作通过表单提交的相应值的键。 尽管这里不处理模型对象,但仍需要一种方法来发回选择。 虽然用于创建或更新模型实例的表单中的键必须与模型的实际属性相对应,但此处的键可以是任何值。 我们只需要它来标识我们的选择,以便我们可以在MoviesController
的show
方法中执行一些逻辑,然后将正确排序的数据发送回去。 在此示例中,我们将键命名为:order
。 第二个论点就是我们想要的选择,在我们的案例中是“Ratings High to Low”
和“Ratings Low to High”
。 现在完成表格所需要做的就是使用submit
助手来实际submit
我们的请求。 如果我们希望按钮说默认save
以外的内容,则可以传递一个可选参数。 我们将继续进行并将其更改为“Submit”
,这将为我们提供以下完整的表格:
# /app/views/movies/show.html.erb<%= form_with(url: movie_path(@movie), method: :get, local: true) do |form| %>
<%= form.select :order, ["Ratings High to Low", "Ratings Low to High"] %>
<%= form.submit "Sort" %>
<% end%>
We’re almost done! Now we actually have to do something with the data we receive from our form. Remember, we sent a get request to our MoviesController
's show
method, therefore we’ll be handling our data there. We’re altering the order of a movie’s reviews based on user input. It makes sense then to create a reviews
instance variable in our show
method. This way we can sort our data in the controller and just iterate through it on our show
page, saving us from having to do any additional logic there. So how do we access that user input? Through the parameters
hash sent back with our request. Remember, we created an :order
key that holds our user’s selection as you can see below
我们快完成了! 现在,我们实际上必须对从表单接收的数据进行处理。 记住,我们向MoviesController
的show
方法发送了一个get请求,因此我们将在那里处理数据。 我们正在根据用户输入更改电影评论的顺序。 然后在我们的show
方法中创建reviews
实例变量是有意义的。 这样,我们可以在控制器中对数据进行排序,并在show
页面上对其进行迭代,从而使我们不必在其中执行任何其他逻辑。 那么我们如何访问该用户输入? 通过parameters
哈希与我们的请求一起发回。 记住,我们创建了一个:order
键,用于保存用户的选择,如下所示
We can create a conditional to determine how our reviews
data should be ordered before sending back that information. If the parameters
we receive have a key of :order
, we know that the user has made a selection. So if parameters
has a key of :order
AND that value is equal to “Ratings High to Low”
, we want to set our reviews
instance variable to equal our movie
instance variable with the ratings_high_to_low
method called on it. Conversely, if parameters
has a key of :order
AND that value is “Ratings Low to High”
, we’ll set our reviews
instance variable to equal @movie.ratings_low_to_high
and send that data back. Otherwise reviews
will simply be equal to @movie.reviews
. The show
method should now look like this:
我们可以创建一个条件来确定在发送回该信息之前如何对我们的reviews
数据进行排序。 如果我们收到的parameters
具有:order
键,我们就知道用户已做出选择。 因此,如果parameters
的键为:order
该值等于“Ratings High to Low”
,则我们希望通过使用ratings_high_to_low
方法将reviews
实例变量设置为等于我们的movie
实例变量。 相反,如果parameters
的键为:order
并且值是“Ratings Low to High”
,则将我们的reviews
实例变量设置为等于@movie.ratings_low_to_high
并将该数据发送回去。 否则reviews
将仅等于@movie.reviews
。 现在, show
方法应如下所示:
# app/controllers/movies_controller.rbdef show
@movie = Movie.find(params[:id]) if params[:order] && params[:order] == "Ratings High to Low"
@reviews = @movie.ratings_high_to_low
elsif params[:order] && params[:order] == "Ratings Low to High"
@reviews = @movie.ratings_low_to_high
else
@reviews = @movie.reviews
end
end
Lastly, we can iterate through our sorted (or unsorted) reviews
instance variable, and display the appropriate data on our show page:
最后,我们可以遍历已排序(或未排序)的reviews
实例变量,并在显示页面上显示适当的数据:
# app/views/movies/show.html.erb
<% @reviews.each do |review| %>
<%= review.review %>
<%= review.rating %>
<% end%>
Here is our final drop down in action:
这是我们的最终操作:
And that’s it!. You can implement a dropdown in any of your views to give users the option to view data in a more meaningful way.
就是这样! 您可以在任何视图中实现下拉菜单,以使用户可以选择以更有意义的方式查看数据。
翻译自: https://medium.com/@rachael.ghorbani/creating-a-sort-drop-down-using-form-with-5b2de4261f2a
vba 下拉列表 排序