在Rails中通过URL传递参数

5

我开始学习Rails,遇到了一个问题,我认为这个问题很简单,但我一直没有找到答案。

我有一个电影目录,索引页面显示了它,显示了几列,我需要将其中两列作为链接。此链接将重新显示索引页面,但按所选标准进行排序。

到目前为止,我只添加了一个链接,如下所示:

%th= link_to 'Movie Title', root_path

但是我无法发送URL参数,以便在控制器中获取并执行排序。实际的控制器如下:

def index
  @movies = Movie.all
end

我想,如果我能在控制器中获取一个参数,那么使用“if”语句就可以完成工作。 我想象一个像这样的URL,其中“1”表示按第一个标准排序:

http://www.mysite/1

我看到了一个类似的解决方案,但我认为这不是一个好的选择。请给予建议。

<%= link_to "Link Title", something__path(:param1 => "value1", :param2 => "value2") %>

我非常希望能得到关于如何修改视图和控制器的建议。我已经在谷歌上搜索了几个解决方案,但是我很难理解这些解决方案。也许有更好的方法来实现这一点。如果有的话,我愿意听取建议。

敬礼,
Jorge Maldonado

4个回答

8

主要问题

这与RESTful路径设计有关。这实际上取决于你试图传递到控制器并在URL中表示的字段类型。

将路径视为访问资源的路由非常重要。

一般来说,有两种表示所需数据的方式:

  • 作为路径变量:其格式为/path/to/resource/:resourceId。使用此格式表示资源本身的属性。
    • 例如,博客文章的ID是博客资源的属性。
  • 作为查询参数:其格式为/path/to/resource?queryKey=queryVal。使用此格式处理元数据和数据操作。
    • 例如,对博客文章进行排序的方式不是博客文章本身的属性,而只是你正在执行的操作。

机制

你的初始猜测实际上非常接近。相反,你需要像这样做:

在你的控制器中:

movie = Movie.find(params[:id])

在你的看法中:

<%= link_to 'View Movie', movie %>

在幕后,Rails 正在执行一些魔法,将其转换为与问题中的代码非常相似的东西。最好让 Rails 自己执行这个魔法,因为它使以后更改变得更容易。
另外,为了明确起见,对于您的情况,使用路径变量(而不是查询参数)是最佳方法。您可以在此处阅读文档中有关路由的更多信息: http://guides.rubyonrails.org/routing.html 跟进问题
回答这个问题(我没有足够的声望来发表评论):
“我感谢您的回答。它很好用。我还有一个问题。这样的链接是什么意思?最后一个参数 (:id) 有什么用? link_to“电影标题”,movies_path(:sort =>“title”),:id =>“title_header””
在 link_to 标记上,:id 添加了一个 id 字段到生成的 HTML 标记中。
这个: link_to "Articles", articles_path, id: "news", class: "article" 生成:<a href="/articles" class="article" id="news">文章</a> 在这里查看Rails文档: http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to
(搜索“Classes and ids for CSS are easy to produce:”)

1

链接实现很好,我没有看到任何问题

<%= link_to "Link Title", some_url_helper_path(:param1 => "value1", :param2 => "value2") %>

从控制器的角度来看,以下是一些筛选数据的选项:

https://makandracards.com/makandra/65468-rails-how-to-get-url-params-without-routing-parameters-or-vice-versa

# On /users?query=Bob&page=2

>> request.params
=> {"page"=>"2", "query"=>"Bob", "controller"=>"users", "action"=>"index"}

>> request.query_parameters
=> {"page"=>"2", "query"=>"Bob"}

>> request.path_parameters
=> {:controller=>"users", :action=>"index"}

然后您可以过滤和清理参数,并将它们传递给.where()方法。

https://github.com/chrisfrank/rack-reducer

GET /artists #=> all artists
GET /artists?name=blake #=> artists named 'blake'
GET /artists?genre=electronic&name=blake #=> electronic artists named 'blake'

控制器:

# app/controllers/artists_controller.rb
class ArtistsController < ApplicationController

  # Step 1: Instantiate a reducer
  ArtistReducer = Rack::Reducer.new(
    Artist.all,
    ->(name:) { where('lower(name) like ?', "%#{name.downcase}%") },
    ->(genre:) { where(genre: genre) },
  )

  # Step 2: Apply the reducer to incoming requests
  def index
    @artists = ArtistReducer.apply(params)
    render json: @artists
  end
end

https://github.com/plataformatec/has_scope - 你可以在这里阅读更多相关信息


0

我会将它们发送到查询字符串中。

例如,接受一个带有查询字符串的URL,如:www.exmaple.com/resource_name/?sortBy=name

params哈希包含:"{"filterBy"=>"name", "controller"=>"resource_name", "action"=>"index", "sortBy"=>"name"}"

现在很容易知道按什么排序了。

确保不要直接将该值注入SQL查询中以避免SQL注入。 可以使用 switch 语句。

如果您不喜欢查询字符串的方法(真的没有理由,但这取决于您),那么请查看Rails路由机制提供了什么。

参考资料:

http://guides.rubyonrails.org/routing.html#the-query-string http://guides.rubyonrails.org/routing.html#non-resourceful-routes


0

你可以按照上面提到的方法添加参数。然后在你的控制器中进行操作。

def index 
if params[:param_1] == "param_one"
@movies = Movie.where(id: 'param_one')
else
@movies = Movie.all
end
end

例如,您的解决方案可能如下所示 =link_to 'xxx',movies_path(:param_one =>“p1”,:param_two =>“p2”) 将调用movies_controller.rb的index操作。


感谢您的回复。它运行良好。我还有一个问题。这样的链接是什么意思?最后一个参数(:id)用于什么?link_to "电影标题", movies_path(:sort => "title"), :id => "title_header" - user3059248

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接