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

Rails has_many :through关联下实现用户加入已有Curso的方法问询

实现方案如下

首先可以明确:这个创建报名关联的逻辑放在InscripcionesController中处理完全符合Rails REST设计规范,也不需要新增new视图、不需要填写表单,只需要三步即可实现需求:


1. 配置路由

在路由文件中给课程资源嵌套一个报名的POST路由,语义更清晰:

# config/routes.rb
Rails.application.routes.draw do
  # 其他原有路由
  resources :cursos do
    post 'inscribir', to: 'inscripciones#create', on: :member
  end
end

配置完成后会生成/cursos/:id/inscribir格式的路由,对应InscripcionesController的create动作。


2. 编写控制器逻辑

不需要编写new动作,直接处理create请求即可,额外增加重复报名的校验避免报错:

# app/controllers/inscripciones_controller.rb
class InscripcionesController < ApplicationController
  # 登录校验,用Devise的话直接用这个过滤器,其他登录方案替换为对应校验逻辑即可
  before_action :authenticate_user!
  before_action :find_curso

  def create
    unless current_user.cursos.include?(@curso)
      current_user.cursos << @curso
      flash[:notice] = "成功加入课程"
    else
      flash[:alert] = "你已经加入过该课程"
    end
    # 完成操作后跳转回课程列表页
    redirect_to cursos_path
  end

  private
  def find_curso
    @curso = Curso.find(params[:id])
  end
end

3. 课程列表页加入按钮

直接用Rails自带的button_to助手生成POST请求按钮,不需要手动写表单:

<!-- app/views/cursos/index.html.erb 遍历课程的位置插入 -->
<% @cursos.each do |curso| %>
  <div class="curso-card">
    <h4><%= curso.nombre %></h4>
    <!-- 其他课程展示信息 -->
    <% if current_user.cursos.include?(curso) %>
      <span>已加入</span>
    <% else %>
      <%= button_to "加入课程", inscribir_curso_path(curso), method: :post %>
    <% end %>
  </div>
<% end %>

如果你不想额外调用InscripcionesController,也可以把create逻辑直接放到CursosController的自定义动作中,不过按职责拆分原则,放在关联资源对应的控制器里后期维护会更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:36:05