Ruby on Rails:实现文章页点击链接加载新建标签局部表单
实现Ruby on Rails文章页动态加载新标签表单
嘿,作为Rails新手要实现这种动态交互确实得费点心思,不过别担心,我会一步步带你搞定这个“点击创建新标签并局部加载表单”的需求!我们优先用Rails 7自带的Turbo来实现(这是现在最简洁的方案),如果你用的是更早版本,我也会补充传统AJAX的做法。
第一步:确认模型关联(先打基础)
首先得确保你的Post和Tag是多对多关联,不然标签和文章没法正确绑定:
# app/models/post.rb class Post < ApplicationRecord has_many :post_tags has_many :tags, through: :post_tags accepts_nested_attributes_for :tags, reject_if: :all_blank, allow_destroy: true end # app/models/tag.rb class Tag < ApplicationRecord has_many :post_tags has_many :posts, through: :post_tags end # app/models/post_tag.rb(连接表模型) class PostTag < ApplicationRecord belongs_to :post belongs_to :tag end
第二步:配置路由
在config/routes.rb里添加标签的基础路由,支持动态响应:
resources :tags, only: [:new, :create]
第三步:完善TagsController
我们需要让标签的new动作返回局部视图,create动作成功后更新文章页的标签选择框:
# app/controllers/tags_controller.rb class TagsController < ApplicationController def new @tag = Tag.new @post_id = params[:post_id] # 接收当前文章ID,方便后续关联 respond_to do |format| format.turbo_stream format.js end end def create @tag = Tag.new(tag_params) if @tag.save @tags = Tag.all # 重新获取所有标签,用于更新选择框 respond_to do |format| format.turbo_stream format.js { render :create_success } end else respond_to do |format| format.turbo_stream { render turbo_stream: turbo_stream.replace('new_tag_form', partial: 'tags/form', locals: { tag: @tag }) } format.js { render :new } end end end private def tag_params params.require(:tag).permit(:name) end end
第四步:创建标签的局部表单
新建app/views/tags/_form.html.erb,这是点击链接后会加载的表单:
<div id="new_tag_form"> <%= form_with model: @tag, data: { turbo_frame: '_top' } do |form| %> <% if @tag.errors.any? %> <div class="alert alert-danger"> <% @tag.errors.full_messages.each do |msg| %> <p><%= msg %></p> <% end %> </div> <% end %> <label>新标签名称</label> <%= form.text_field :name, required: true, class: "form-control mb-2" %> <%= hidden_field_tag :post_id, @post_id if @post_id %> <div> <%= form.submit "创建标签", class: "btn btn-primary me-2" %> <%= link_to "取消", "#", class: "btn btn-secondary", data: { action: 'click->turbo#remove' } %> </div> <% end %> </div>
第五步:在文章表单里添加“创建新标签”链接
修改你现有的文章新建/编辑视图,在标签选择框旁添加链接和表单容器:
<label>Tags </label><br/> <%= form.collection_select(:tag_ids, Tag.all, :id, :name, {}, :multiple => true, id: "post_tag_ids", class: "form-control mb-2") %> <br/> <%= link_to "创建新标签", new_tag_path(post_id: @post.id), data: { turbo_frame: 'new_tag_form', action: 'click->turbo#append' }, class: "text-primary" %> <!-- 用来承载新标签表单的容器 --> <div id="new_tag_form"></div> <!-- 保留你原有的其他表单元素 --> <label>Title </label><br/><%= form.text_field :title, required: true %><br/><br/> <label>Content </label> <br/> <%= form.text_area :content, required: true %><br/><br/> <%= form.submit %>
第六步:创建Turbo流模板更新标签选择框
当标签创建成功后,自动更新文章页的标签下拉框,新建app/views/tags/create.turbo_stream.erb:
<%# 替换旧的标签选择框,加载新的标签列表 %> <%= turbo_stream.replace "post_tag_ids", partial: "posts/tag_select", locals: { form: form, tags: @tags } %> <%# 移除新标签表单 %> <%= turbo_stream.remove "new_tag_form" %>
再创建标签选择框的局部视图app/views/posts/_tag_select.html.erb方便复用:
<%= form.collection_select(:tag_ids, tags, :id, :name, {}, :multiple => true, id: "post_tag_ids", class: "form-control") %>
如果你用的是Rails 6及更早版本(不用Turbo)
用传统AJAX实现:
- 修改“创建新标签”链接:
<%= link_to "创建新标签", new_tag_path(post_id: @post.id), remote: true, class: "text-primary", id: "new_tag_link" %> <div id="new_tag_form"></div>
- 创建
app/views/tags/new.js.erb:
$("#new_tag_form").html("<%= j render 'tags/form', tag: @tag, post_id: @post_id %>");
- 创建
app/views/tags/create_success.js.erb:
// 更新标签选择框 $("#post_tag_ids").html("<%= j options_from_collection_for_select(Tag.all, :id, :name, @post.tag_ids) %>"); // 清空新标签表单 $("#new_tag_form").empty();
这样点击“创建新标签”就能局部加载表单,创建成功后新标签会自动出现在下拉框里,完全不用刷新页面~
内容的提问来源于stack exchange,提问作者Gomathi
相关产品推荐
相关产品推荐

