You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 5.1中如何通过link_to提交订阅(Subscription)创建请求

嘿,我来帮你搞定这个问题!要把表单换成link_to提交订阅请求,只需要利用Rails的UJS特性让链接发送POST请求,再配合正确的路由和控制器逻辑就行,具体步骤如下:

1. 确认路由设置

首先得在routes.rb里把Subscription设为Project的嵌套资源,这样才能生成正确的创建路径:

resources :projects do
  resources :subscriptions, only: [:create] # 只保留create动作就够了
end

这会生成project_subscriptions_path(@project)路由,指向SubscriptionsController#create。

2. 优化控制器的create动作

为了安全,别直接从参数接收user_id(防止用户篡改),而是在控制器里用current_user直接赋值。修改subscriptions_controller.rb:

def create
  @project = Project.find(params[:project_id])
  # 通过项目关联构建订阅,直接绑定当前用户
  @subscription = @project.subscriptions.build(user: current_user)
  
  if @subscription.save
    redirect_to @project, notice: "订阅成功!"
  else
    redirect_to @project, alert: "订阅失败,请重试。"
  end
end

private
# 因为已经在控制器里赋值了user_id,这里参数校验可以简化
def subscription_params
  params.require(:subscription).permit()
end

现在就可以把原来的链接改成发送POST请求的版本,不用传user_id(控制器会自动处理):

<%= link_to "Enroll", project_subscriptions_path(@task.project), 
      method: :post, 
      data: { confirm: "确定要订阅这个项目吗?" }, # 可选:添加确认提示
      class: "your-button-class" %>
  • method: :post告诉Rails这个链接要发送POST请求(默认是GET)
  • Rails会自动带上CSRF token(只要你的布局里有<%= csrf_meta_tags %>,这是Rails默认配置)
  • 加上data: { confirm: ... }可以给用户加个确认弹窗,提升体验

如果一定要通过参数传值(不推荐),也可以这么写:

<%= link_to "Enroll", project_subscriptions_path(@task.project), 
      method: :post,
      params: { subscription: { project_id: @task.project.id, user_id: current_user.id } } %>

但还是建议用控制器绑定current_user的方式,更安全。

最后检查

确保页面加载了Rails UJS(Rails 5.1默认包含jquery_ujs),这样method: :post才能生效,把GET请求转换成POST。

内容的提问来源于stack exchange,提问作者Prometheus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:44:17