Rails项目详情页嵌套属性表单问题:修改ProjectLine状态
Hey there! Let's get this working smoothly for you. Your goal is to mark individual ProjectLine entries as complete (status = 4) from the Project show page—here's a clean, secure way to implement that:
Step 1: Add a Custom Route
First, let's set up a dedicated route for the "mark as complete" action. Open config/routes.rb and add this inside your routes block:
resources :project_lines do member do patch :complete # This creates a /project_lines/:id/complete route end end
Using patch makes sense here because we're only updating a single field (status) rather than the entire resource.
Step 2: Add the Controller Action
Next, open app/controllers/project_lines_controller.rb and add the complete action. This will handle finding the ProjectLine, updating its status, and redirecting back to the Project show page:
class ProjectLinesController < ApplicationController # ... your existing actions ... def complete @project_line = ProjectLine.find(params[:id]) if @project_line.update(status: 4) # Redirect back to the parent project with a success message redirect_to project_path(@project_line.project), notice: "Task marked as complete!" else # Handle failure (e.g., validation errors) redirect_to project_path(@project_line.project), alert: "Oops, couldn't mark this task as complete." end end end
This is more secure than relying on a hidden field because we explicitly set the status to 4 in the controller—users can't tamper with this value in their browser.
Step 3: Update the View
Now let's tweak your view code to use the new route. We have two clean options:
Option 1: Using a Form (matches your original semantic_form_for approach)
<%= @project.name %> <% @project.project_lines.each do |project_line| %> <%= project_line.description %> <%= semantic_form_for project_line, url: complete_project_line_path(project_line), method: :patch do |f| %> <%= f.submit 'COMPLETE', class: 'btn btn-primary btn-md' %> <% end %> <% end %>
Option 2: Using a Link (simpler, no form needed)
If you don't need a form, you can use link_to instead—just make sure your Rails app has UJS/Turbo enabled (which it does by default in modern Rails versions):
<%= @project.name %> <% @project.project_lines.each do |project_line| %> <%= project_line.description %> <%= link_to 'COMPLETE', complete_project_line_path(project_line), method: :patch, class: 'btn btn-primary btn-md' %> <% end %>
Quick Notes
- Double-check that your
ProjectLinemodel has astatusattribute (you can confirm this via your database migration if needed). - If you have validations on
ProjectLine, the controller'supdatecall will fail if those validations aren't met—feel free to adjust the error message to fit your use case.
内容的提问来源于stack exchange,提问作者catmal

