在Rails中传递URL中的参数

时间:2017-02-11 19:02:21

标签: ruby-on-rails

我开始学习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") %>

我非常感谢有关如何修改视图和控制器的任何建议。我已经搜索了几个解决方案,但我很难理解解决方案。也许有更好的方法来实现这一目标。如果是这样,那么我准备好听。

尊敬,
豪尔赫马尔多纳多

4 个答案:

答案 0 :(得分:5)

主要问题

这归结为RESTful路径设计。这实际上取决于您尝试传递给控制器​​并在URL中表示的字段类型。

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

一般来说,有两种方法可以表示您想要的数据:

  • 作为路径变量:这些变量的形式为/path/to/resource/:resourceId。使用此格式表示资源本身的属性。
    • e.g。博客上的帖子ID是博客资源的属性。
  • 作为查询参数:这些参数的格式为/path/to/resource?queryKey=queryVal。将此格式用于数据的元数据和操作。
    • e.g。您对博客帖子进行排序的方式不是博客帖子本身的属性,而只是您正在对其执行的操作。

力学

你最初的猜测实际上非常接近。你想要的是这样的东西:

在您的控制器中:

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

在您看来:

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

在引擎盖下,Rails正在执行一些魔术,将其变成与问题中的代码非常相似的东西。最好让Rails自己执行这个魔术,因为它可以让以后更容易改变。

另外,为了清楚起见,使用路径变量(而不是查询参数)是适合您情况的最佳方法。您可以在此处的文档中阅读有关路由的更多信息: http://guides.rubyonrails.org/routing.html

后续问题

回答这个问题(我还没有足够的回复评论):

  

感谢您的回复。它工作正常。我还有一个问题。这样的链接是什么意思?最后一个参数(:id)用于什么? link_to "Movie Title", movies_path(:sort => "title"), :id => "title_header"

link_to代码上,:id会在生成的HTML代码中添加id字段。

此: link_to "Articles", articles_path, id: "news", class: "article"

生成:<a href="/articles" class="article" id="news">Articles</a>

请参阅此处的Rails文档: http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to
(搜索“CSS的类和ID很容易产生:”)

答案 1 :(得分:0)

您可以做的是添加上面提到的参数。 比在你的控制器中你可以做

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

等。你的解决方案可能是这样的 = link_to&#39; xxx&#39;,movies_path(:param_one =&gt;&#34; p1&#34;,:param_two =&gt;&#34; p2&#34;) 将调用movies_controller.rb的索引操作。

答案 2 :(得分:0)

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

例如,使用带有查询字符串的URL,例如:PendingIntent pendingIntent=PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

www.exmaple.com/resource_name/?sortBy=name哈希包含:params

现在很容易知道要分类的内容。

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

如果您不喜欢查询字符串方法(确实没有理由,但这取决于您),请查看Rails路由机制提供的内容。

参考文献:

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

答案 3 :(得分:0)

链接实现很好,我看不出有什么不好

<%= 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-您可以在此处详细了解