如何在不在rails中创建路由的情况下将操作链接到按钮?

我在我的Rails应用程序中有一个投票按钮,并允许用户投票我创建了一个连接按钮和相应操作的路线。

路线:

/posts/1/vote_up 

但是在其他ROR网站上,我一直在分析他们可以在不创建路线的情况下完成同样的事情(或者至少在没有向公众用户展示的情况下)。 一个例子是Producthunt ,有一个投票按钮,但当你将鼠标hover在它上面时,没有路由或URL映射到它。

怎么做到这一点? 我可以将操作链接到按钮而不创建路径吗?

在不了解您的控制器或模型的情况下,您将如何做到这一点。 这是一个无声的Ajax调用。

 <%= form_tag(post, id: "post" + String(post.id),method: :patch, remote: true, authenticity_token: true) do %> <%= hidden_field_tag "post[voter]", current_user.id %> <%= hidden_field_tag "post[vote_up]", true %> <%= button_tag "Up Vote", onclick: "$('#post#{String(post.id)}').trigger('submit.rails');" %> <% end %> 

method: :patch将从您的控制器调用您的更新方法。 所以现在你不需要定义一条路线。

如果你在数据库中进行增量,则需要在控制器的更新方法中添加逻辑以捕获参数,删除它,然后增加计数。 您可能还希望实现一种方式,即当前用户每个post只能投票一次。

在你的控制器中,如果你想要format.js {render nothing: true}你可以添加一个没有任何回复的JavaScript响应。

 def update respond_to do |format| if @post.update(post_params) format.js {render nothing: true} format.html { redirect_to @post, notice: 'Post was successfully updated.' } format.json { render :show, status: :ok, location: @post } else format.js {render nothing: true} format.html { render :edit } format.json { render json: @post.errors, status: :unprocessable_entity } end end end 

回应:

如果我只需要一个’link_to’来调用控制器中的一个函数,并使用静默AJAX(而不是像你的例子那样执行form_tag),我将如何实现它?

链接本身不会发送任何数据……这就是您必须定义路由的原因。 除非你给链接参数。

 <%= link_to "Up Vote", post_path(@post, post: {up_vote: true}) %> 

您也可以为此提供一种方法。 所以如果你把method: :patch它应该调用你的更新方法。

 <%= link_to "Up Vote", post_path(@post, post: {up_vote: true}), method: :patch %> 

这些示例将以params的forms在url中添加一堆文本:

 # posts/1?post[up_vote]=true 

所以这可以在不配置routes.rb文件的情况下工作。 但是您可能需要添加更多参数并修改控制器来处理这些参数。


我的答案:

我在这里写的内容不会显示为一个表单,但看起来就像一个按钮。 您可以将button_tag替换为支持onclick任何其他内容,以将您想要的数据提交给服务器。

您可以使用表单的隐藏字段来传递要使用的数据,而不是超链接引用。 如果不给它一个hpyerlink引用,你实际上不能使用link_to。 所以替代它就是content_tag 'a' 。 只需替换上一个表单button_tag行即可生成此行。

 <%= form_tag(post, id: "post" + String(post.id),method: :patch, remote: true, authenticity_token: true) do %> <%= hidden_field_tag "post[voter]", current_user.id %> <%= hidden_field_tag "post[vote_up]", true %> <%= content_tag 'a', "Up Vote", onclick: "$('#post#{String(post.id)}').trigger('submit.rails');" , style: 'cursor: pointer' %> <% end %> 

现在看来你有一个常规链接,当你点击它时鼠标会改变。 现在的问题是当人们点击“向上投票”链接时,看起来没有任何反应。 您需要添加CSS和/或JS操作,以便在用户单击链接后更改其视图。 因此,除了执行提交的onlcick您还需要调用Javascript方法将您的内容从“Up Vote”修改为“Thanks for Voting!”。 除此之外,它不会“显示”为一个表单,并且您有链接。

如果由于某种原因确实希望在单击链接后重新加载页面,则可以更改JS响应。

 format.js { redirect_to @post, notice: 'Thanks for voting!' } 

试试这个。 这是我们在命名路由之前使用的东西:

 link_to "Link to listing new", controller: :listings, action: :new #or link_to "string method", "/listings/new"