Rails:使用链接设置值
我需要帮助尝试创建提交编辑表单的链接。
假设我有一个对象列表
Object - Color - Own?
Ball - Red - false - [button]
Hat - Blue - true - [button]
Shoe - Green - false - [button]
,当我单击[按钮]时,我想设置“自己的?”为真。
路线
resources :toys
控制器
def edit
@toy = Toy.find(params[:id])
end
def update
@toy = Toy.find(params[:id])
if @Toy.update_attributes(params[:toy])
flash[:notice] = "Toy Updated"
redirect_to @toy
else
render 'edit'
end
end
视图
<h2>Toys</h2>
<% if @toys %>
<% @toys.each do |toy| %>
<%= toy.name %> - <%= link_to 'Set Own', edit_toy_path(:id=>toy.id, :owned=>'true')%>
<br/>
<% end %>
<% else %>
None
<% end %>
I need help trying to create a link that submits an edit form.
Let's say I have a list of objects
Object - Color - Own?
Ball - Red - false - [button]
Hat - Blue - true - [button]
Shoe - Green - false - [button]
When I click on the [button] I want to set "Own?" to True.
Routes
resources :toys
Controller
def edit
@toy = Toy.find(params[:id])
end
def update
@toy = Toy.find(params[:id])
if @Toy.update_attributes(params[:toy])
flash[:notice] = "Toy Updated"
redirect_to @toy
else
render 'edit'
end
end
View
<h2>Toys</h2>
<% if @toys %>
<% @toys.each do |toy| %>
<%= toy.name %> - <%= link_to 'Set Own', edit_toy_path(:id=>toy.id, :owned=>'true')%>
<br/>
<% end %>
<% else %>
None
<% end %>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
link_to
方法调用的edit_toy_path
方法将转到控制器内的edit
操作。我猜你想要的不会是 update 方法。您的
link_to
需要更改为以下内容:但我对这种特殊方法提出质疑。我认为该变量不会在更新操作中正确更新,因为它没有命名为
update_attributes
期望的正确params[:toy]
对象。在我的快速而肮脏的测试中,我无法将其正确地放入命名空间。当我遇到像您所描述的情况时,我通常会设置另一个操作,例如
toggle_ownership
,并使用:remote => 从我的
link_to
调用该操作; true 选项。然后控制器根据需要切换属性。因此,我的路线看起来像这样:
我的视图看起来像
控制器设置变量并渲染回一个
toggle_ownership.js.erb
文件,该文件更新页面的相应部分。希望有帮助!
The
edit_toy_path
method that yourlink_to
method is calling is going to theedit
action inside your controller. It's not going to theupdate
method that I'm guessing you want.Your
link_to
will need to change to something like:But I question this particular approach. I don't think the variable will update correctly in the update action because it is not namespaced to the proper
params[:toy]
object thatupdate_attributes
is expecting. And in my quick and dirty tests I couldn't get it to namespace properly.When I have a situation like the one that you are describing I usually setup another action, like
toggle_ownership
and I call that from mylink_to
with a:remote => true
option. Then the controller toggles the attributes as desired.Thus, my routes looks something like:
And my view looks like
The controller sets the variable and renders back a
toggle_ownership.js.erb
file that updates the appropriate section of the page.Hope that helps!
这完全取决于您如何设置控制器操作。我不完全确定我理解你想如何使用你的,但我有一个类似的案例,我将向你展示我认为你应该能够适应你的情况。
就我而言,我有一个菜单按钮,它在会话中设置一个值,以在用户查看的任何视图中保持菜单面板打开或关闭。
首先,您需要一个控制器操作来完成您感兴趣的工作。我创建了一个“SharedController”,它处理不属于任何特定视图或其他控制器的应用程序范围的事情。
此控制器操作可以在会话中设置两个值之一:“admin_menu”(布尔值)或“advanced_search”(布尔值)。然后某些视图会询问 admin_menu 或 advance_search 的会话值是否为 true,如果是,则显示该视图。
您可以使用相同的逻辑。类似于:
要使用链接触发此控制器操作,您需要有一个接受 GET 请求的路由。
edit
是一个合乎逻辑的选择。注意:我认为
SharedController
比SharedsController
更有意义,而edit_shared_path
比edit_shareds_path
更有意义,所以我必须指定:controller =>; 'shared'在我的routes.rb中。
然后你只需要一个带有参数的url链接。要将参数添加到路径上,只需将它们添加到路径帮助器中,如下所示:
您可以通过以下方式在控制器中检索这些参数:
将其设置为链接,如下所示:
注意:最好通过 AJAX 执行此操作,因此可以请务必设置
:remote=>true
。如果您不使用 AJAX,那么您需要在控制器中指定一个重定向,以便在触发此链接后应加载哪个页面。对于我的管理菜单首选项链接,我需要一个包含两个可能的链接州。我使用助手生成这些:
在视图中,我只是使用
admin_toggle_button
调用它。如果您愿意,您可以做类似的事情,但这是可选的。我希望这能让您走上正轨,如果您有任何疑问,请告诉我。
编辑:根据您的评论:
链接发出 GET 请求,这意味着您将进行编辑操作。请参阅:http://guides.rubyonrails.org/routing.html#crud -verbs-and-actions
进一步的问题是,您有
resources :toys
而不是resource :shared
(我用于此目的)。这意味着您的链接助手已经期望编辑特定的玩具,而不是处理单个资源。请参阅:http://guides.rubyonrails.org/routing.html#singular-resources如果您将其更改为:
...并将控制器中的编辑操作设置为以下内容,则链接将起作用:
请参阅:http://guides.rubyonrails.org/layouts_and_rendering.html #using-head-to-build-header-only-responses
现在,请注意,您确实应该只使用 AJAX 链接执行此操作,并且通常不应该使用您的“真正的”控制器。原因是,现在这是唯一可以通过 EDIT 处理的操作,因此您的正常
toys#edit
视图将不再起作用。您可以通过创建新操作和新路线来解决此问题,例如:
然后只需采用上面相同的方法并将其命名为
set_ownership
而不是edit
。 IE:希望一切都有意义。
This is all about how you setup your controller actions. I'm not totally sure I understand how you want to use yours, but I have a similar case that I'll show you which I think you should be able to adapt to your situation.
In my case, I have a menu button that sets a value in the session to either keep a menu panel open or closed across any views a user looks at.
First, you need a controller action that is going to do the work you're interested in. I created a "SharedController" which handles application-wide things that don't belong to any particular view or other controller.
This controller action can set one of two values in the session, either: "admin_menu" (boolean) or "advanced_search" (boolean). Then certain views ask whether the session value for admin_menu or advanced_search is true, and if so they show the view.
You could use the same logic. Something like:
To trigger this controller action with a link you need to have a route that accepts GET requests.
edit
is a logical choice.Note: I think
SharedController
makes more sense thanSharedsController
, andedit_shared_path
makes more sense thanedit_shareds_path
, so I had to specify:controller => 'shared'
in my routes.rb.Then you just need a link to a url with params. To add params onto a path you just add them to the path helper, like so:
You can retrieve these params in your controller via:
Make this a link like so:
NOTE: It's best to do this via AJAX, so be sure to set
:remote=>true
. If you don't use AJAX then you need to specify a redirect in your controller for what page should be loaded after this link is triggered.In the case of my admin menu preference link, I need a link with two possible states. I generate these using a helper:
In a view I just call this using
admin_toggle_button
. You can do something similar if you like, but it's optional.I hope that gets you on the right track, let me know if you have any questions.
EDIT: Based on your comment:
Links issue GET requests, which mean you're going to the EDIT action. See: http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
A further issue, you have
resources :toys
instead ofresource :shared
(which I used for this purpose). This means your link helper is already expecting a specific toy to edit, rather than handling a singular resource. See: http://guides.rubyonrails.org/routing.html#singular-resourcesYour link would work if you changed it to be:
... and set your edit action in your controller to the following:
See: http://guides.rubyonrails.org/layouts_and_rendering.html#using-head-to-build-header-only-responses
Now, be aware, you really should only do this with AJAX links, and you should normally not do it with your "real" controller. The reason is, now this is the only action that can be processed by EDIT, so your normal
toys#edit
view would no longer work.You can get around this by create a new action and a new route, for instance:
Then simply take the same method above and call it
set_ownership
instead ofedit
. IE:Hope that all makes sense.