ruby @milestone_options中的无变量

xv8emn3q  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(74)

我在尝试创建新任务时遇到了这个Rails错误:

NoMethodError in Tasks#create

Showing /workspace/the-goal/app/views/tasks/_form.html.erb where line #10 raised:

undefined method `map' for nil:NilClass

        container.map do |element|
                 ^^^^

Extracted source (around line #10):

  <div>
    <%= form.label :milestone %>
    <%= form.select(:milestone_id, @milestone_options, :selected => params[:milestone_id]) %>
  </div>

  <div>

Trace of template inclusion: #<ActionView::Template app/views/tasks/new.html.erb locals=[]>

Rails.root: /workspace/the-goal
Application Trace | Framework Trace | Full Trace
app/views/tasks/_form.html.erb:10
app/views/tasks/_form.html.erb:1
app/views/tasks/new.html.erb:5
app/controllers/tasks_controller.rb:36:in `block (2 levels) in create'
app/controllers/tasks_controller.rb:32:in `create'
Request

Parameters:

{"authenticity_token"=>"Zgc5P_w27Hodc0XQTG8-pVRNrugE9bOFqIANwfWeRdPgFKtKIkrnfMWdVnRvgYSXCzuy1uWAu4EHI6np6SS1dA",
 "task"=>{"name"=>"[FILTERED]", "milestone_id"=>"1", "duration"=>"4", "priority"=>"No priority", "description"=>"", "status"=>"0"},
 "commit"=>"Create Task"}

我有三个模型:
project.rb:

# == Schema Information
#
# Table name: projects
#
#  id         :bigint           not null, primary key
#  deadline   :date
#  name       :string
#  priority   :integer
#  progress   :integer
#  status     :integer
#  created_at :datetime         not null
#  updated_at :datetime         not null
#  account_id :integer
#
class Project < ApplicationRecord
  acts_as_tenant :account
  has_rich_text :description
  has_many :milestones
  validates :name, :progress, :priority, :status, presence: true

  # Broadcast changes in realtime with Hotwire
  after_create_commit -> { broadcast_prepend_later_to :projects, partial: "projects/index", locals: {project: self} }
  after_update_commit -> { broadcast_replace_later_to self }
  after_destroy_commit -> { broadcast_remove_to :projects, target: dom_id(self, :index) }

  enum priority: [:"No priority", :Low, :Medium, :High]
  enum status: [:"Not started", :"In progress", :Waiting, :Done]

  def priority
    super.to_s.humanize
  end

  def status
    super.to_s.humanize
  end
end

milestone.rb:

# == Schema Information
#
# Table name: milestones
#
#  id         :bigint           not null, primary key
#  deadline   :date
#  name       :string
#  priority   :integer
#  status     :integer
#  created_at :datetime         not null
#  updated_at :datetime         not null
#  account_id :bigint           not null
#  project_id :bigint           not null
#
# Indexes
#
#  index_milestones_on_account_id  (account_id)
#  index_milestones_on_project_id  (project_id)
#
# Foreign Keys
#
#  fk_rails_...  (account_id => accounts.id)
#  fk_rails_...  (project_id => projects.id)
#
class Milestone < ApplicationRecord
  acts_as_tenant :account
  has_rich_text :description
  belongs_to :project
  has_many :tasks
  validates :name, :priority, :status, presence: true
  validates :project, presence: true

  # Broadcast changes in realtime with Hotwire
  after_create_commit -> { broadcast_prepend_later_to :milestones, partial: "milestones/index", locals: {milestone: self} }
  after_update_commit -> { broadcast_replace_later_to self }
  after_destroy_commit -> { broadcast_remove_to :milestones, target: dom_id(self, :index) }

  enum priority: [:"No priority", :Low, :Medium, :High]
  enum status: [:"Not started", :"In progress", :Waiting, :Done]
  

  def priority
    super.to_s.humanize
  end

  def status
    super.to_s.humanize
  end
end

task.rb:

# == Schema Information
#
# Table name: tasks
#
#  id           :bigint           not null, primary key
#  description  :text
#  duration     :integer
#  name         :string
#  priority     :integer
#  status       :boolean
#  created_at   :datetime         not null
#  updated_at   :datetime         not null
#  account_id   :bigint           not null
#  milestone_id :bigint           not null
#
# Indexes
#
#  index_tasks_on_account_id    (account_id)
#  index_tasks_on_milestone_id  (milestone_id)
#
# Foreign Keys
#
#  fk_rails_...  (account_id => accounts.id)
#  fk_rails_...  (milestone_id => milestones.id)
#
class Task < ApplicationRecord
  acts_as_tenant :account
  has_rich_text :description
  belongs_to :milestone
  validates :name, :priority, :status, :duration, presence: true
  validates :milestone, presence: true

  # Broadcast changes in realtime with Hotwire
  after_create_commit  -> { broadcast_prepend_later_to :tasks, partial: "tasks/index", locals: { task: self } }
  after_update_commit  -> { broadcast_replace_later_to self }
  after_destroy_commit -> { broadcast_remove_to :tasks, target: dom_id(self, :index) }

  enum priority: [:"No priority", :Low, :Medium, :High]

  def priority
    super.to_s.humanize
  end

end

Military Controller看起来像这样:

class MilestonesController < ApplicationController
  def new
    @milestone = Milestone.new
    @project_options = Project.all.map { |p| [p.name, p.id] }
    @projects = Project.all
    @project = Project.find(params[:project_id]) if params[:project_id]
  end

  def index
    @project = Project.ids
  end

  def show
    @milestone = Milestone.find(params[:id])
    @tasks = @milestone.tasks

    if request.path != milestone_path(@milestone)
      redirect_to @milestone, :status => :moved_permanently
    end
  end

  def edit
    @milestone = Milestone.find(params[:id])
    @project_options = Project.all.map { |p| [p.name, p.id] }
  end

  def create
    @milestone = Milestone.new(milestone_params)
    respond_to do |format|
      if @milestone.save
        format.html { redirect_to milestones_url, notice: "Milestone was successfully created." }
      else
        format.html { render :new, status: :unprocessable_entity }
      end
    end
  end

  def update
    @milestone = Milestone.find(params[:id])
    respond_to do |format|
      if @milestone.update(milestone_params)
        format.html { redirect_to milestones_url, notice: "Milestone was successfully updated." }
      else
        format.html { render :edit, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @milestone = Milestone.find(params[:id])
    respond_to do |format|
      if @milestone.destroy
        format.html { redirect_to milestones_url, notice: "Milestone was successfully destroyed." }
      else
        format.html { render :delete, status: :unprocessable_entity }
      end
    end
  end

  private

  # Only allow a list of trusted parameters through.
  def milestone_params
    params.require(:milestone).permit(:name, :deadline, :priority, :status, :description, :project_id)
  end
end

和任务控制器:

class TasksController < ApplicationController
  def new
    @task = Task.new
    @milestones = Milestone.all
    @milestone_options = @milestones.map { |m| [m.name, m.id] }
  end
    

  def index
    @milestone = Milestone.ids
    # @task = Task.all
  end

  def show
    @task = Task.find(params[:id])

    if request.path != task_path(@task)
      redirect_to @task, :status => :moved_permanently
    end
  end

  def edit
    @task = Task.find(params[:id])
    @milestone_options = Milestone.all.map { |p| [p.name, p.id] }
  end

  def create
    @task = Task.new(task_params)
    # @milestone_options = Milestone.all.map { |p| [p.name, p.id] }
    # @milestones = Milestone.all
    # @milestone = Milestone.find(params[:milestone_id]) if params[:milestone_id]
    respond_to do |format|
      if @task.save
        format.html { redirect_to tasks_url, notice: "Task was successfully created." }
      else
        format.html { render :new, status: :unprocessable_entity }
      end
    end
  end
  

  def update
    @task = Task.find(params[:id])
    respond_to do |format|
      if @task.update(task_params)
        format.html { redirect_to tasks_url, notice: "Task was successfully updated." }
      else
        format.html { render :edit, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @task = Task.find(params[:id])
    respond_to do |format|
      if @task.destroy
        format.html { redirect_to tasks_url, notice: "Task was successfully destroyed." }
      else
        format.html { render :delete, status: :unprocessable_entity }
      end
    end
  end
  
  private

  # Only allow a list of trusted parameters through.
  def task_params
    params.require(:task).permit(:name, :priority, :status, :description, :duration, :milestone_id)
  end
end

我的任务表单看起来像这样:

<%= form_with model: @task do |form| %>

  <div>
    <%= form.label :name %>
    <%= form.text_area :name %>
  </div>

  <div>
    <%= form.label :milestone %>
    <%= form.select(:milestone_id, @milestone_options, :selected => params[:milestone_id]) %>
  </div>

  <div>
    <%= form.label :duration %>
    <%= form.number_field :duration %> %
  </div>

  <div>
    <%= form.label :priority %>
    <%= form.select :priority, [["No priority", "No priority"], ["Low", "Low"], ["Medium", "Medium"], ["High", "High"]] %>
  </div>

  <div>
    <%= form.label :description %>
    <%= form.rich_text_area :description %>
  </div>

  <div>
    <%= form.label :status, "Done" %>
    <%= form.check_box :status %>
  </div>

  <div>
    <%= form.submit %>
  </div>
<% end %>

当我尝试创建里程碑时,它可以工作,但当我创建任务iz时失败。哪里有错误代码?
任务的工作方式应该与里程碑相同。但里程碑属于项目,任务属于里程碑。
更新:当我在任务控制器上取消注解第29行时,错误不会出现,但任务不会创建。下面是日志:

Started POST "/tasks" for 217.67.18.195 at 2023-09-14 17:45:45 +0000
Cannot render console from 217.67.18.195! Allowed networks: 127.0.0.0/127.255.255.255, ::1
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
Processing by TasksController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"1zgJMGslsBavT9pavWpA55xG9JdHSID9Lif45OyexwZRK5tFtVm7EHehyf6ehPrVwzDoqaY9iPmBhFzM8CQ3oQ", "task"=>{"name"=>"[FILTERED]", "milestone_id"=>"1", "duration"=>"4", "priority"=>"No priority", "description"=>"", "status"=>"0"}, "commit"=>"Create Task"}
  Account Load (0.6ms)  SELECT "accounts".* FROM "accounts" INNER JOIN "account_users" ON "accounts"."id" = "account_users"."account_id" WHERE "account_users"."user_id" = $1 AND "accounts"."id" IS NULL LIMIT $2  [["user_id", 1], ["LIMIT", 1]]
  ↳ app/controllers/concerns/set_current_request_details.rb:35:in `account_from_session'
  Account Load (0.4ms)  SELECT "accounts".* FROM "accounts" INNER JOIN "account_users" ON "accounts"."id" = "account_users"."account_id" WHERE "account_users"."user_id" = $1 ORDER BY "accounts"."created_at" ASC LIMIT $2  [["user_id", 1], ["LIMIT", 1]]
  ↳ app/controllers/concerns/set_current_request_details.rb:40:in `fallback_account'
  Notification Count (0.5ms)  SELECT COUNT(*) FROM "notifications" WHERE "notifications"."recipient_id" = $1 AND "notifications"."recipient_type" = $2 AND "notifications"."read_at" IS NULL AND "notifications"."account_id" = $3  [["recipient_id", 1], ["recipient_type", "User"], ["account_id", 1]]
  ↳ app/controllers/concerns/users/navbar_notifications.rb:11:in `set_notifications'
  Notification Count (0.4ms)  SELECT COUNT(*) FROM "notifications" WHERE "notifications"."recipient_id" = $1 AND "notifications"."recipient_type" = $2 AND "notifications"."read_at" IS NULL AND ("notifications"."account_id" = $3 OR "notifications"."account_id" IS NULL)  [["recipient_id", 1], ["recipient_type", "User"], ["account_id", 1]]
  ↳ app/controllers/concerns/users/navbar_notifications.rb:12:in `set_notifications'
  Milestone Load (0.4ms)  SELECT "milestones".* FROM "milestones" WHERE "milestones"."account_id" = $1  [["account_id", 1]]
  ↳ app/controllers/tasks_controller.rb:29:in `map'
  TRANSACTION (0.2ms)  BEGIN
  ↳ app/controllers/tasks_controller.rb:33:in `block in create'
  Account Load (0.4ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/tasks_controller.rb:33:in `block in create'
  Milestone Load (0.3ms)  SELECT "milestones".* FROM "milestones" WHERE "milestones"."account_id" = $1 AND "milestones"."id" = $2 LIMIT $3  [["account_id", 1], ["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/tasks_controller.rb:33:in `block in create'
  TRANSACTION (0.2ms)  ROLLBACK
  ↳ app/controllers/tasks_controller.rb:33:in `block in create'
  Rendering layout layouts/application.html.erb
  Rendering tasks/new.html.erb within layouts/application
  Rendered tasks/_form.html.erb (Duration: 6.0ms | Allocations: 3236)
  Rendered tasks/new.html.erb within layouts/application (Duration: 6.2ms | Allocations: 3299)
  Rendered shared/_favicons.html.erb (Duration: 0.0ms | Allocations: 10)
  Rendered shared/_payments_dependencies.html.erb (Duration: 0.0ms | Allocations: 20)
  Rendered shared/_flash.html.erb (Duration: 0.1ms | Allocations: 33)
  Rendered shared/_left_nav.html.erb (Duration: 0.2ms | Allocations: 127)
  Announcement Load (0.3ms)  SELECT "announcements".* FROM "announcements" ORDER BY "announcements"."published_at" DESC LIMIT $1  [["LIMIT", 1]]
  ↳ app/helpers/announcements_helper.rb:19:in `unread_announcements_class'
  Rendered shared/_right_nav.html.erb (Duration: 1.9ms | Allocations: 774)
  Rendered shared/_notifications.html.erb (Duration: 0.3ms | Allocations: 266)
  User Load (0.6ms)  SELECT "users".* FROM "users" INNER JOIN "account_users" ON "users"."id" = "account_users"."user_id" WHERE "account_users"."account_id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["account_id", 1], ["LIMIT", 1]]
  ↳ app/helpers/accounts_helper.rb:8:in `account_avatar'
  ActiveStorage::Attachment Load (0.3ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 1], ["record_type", "User"], ["name", "avatar"], ["LIMIT", 1]]
  ↳ app/helpers/avatar_helper.rb:5:in `avatar_url_for'
  CACHE User Load (0.0ms)  SELECT "users".* FROM "users" INNER JOIN "account_users" ON "users"."id" = "account_users"."user_id" WHERE "account_users"."account_id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["account_id", 1], ["LIMIT", 1]]
  ↳ app/helpers/accounts_helper.rb:8:in `account_avatar'
  CACHE ActiveStorage::Attachment Load (0.0ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 1], ["record_type", "User"], ["name", "avatar"], ["LIMIT", 1]]
  ↳ app/helpers/avatar_helper.rb:5:in `avatar_url_for'
  Account Exists? (0.5ms)  SELECT 1 AS one FROM "accounts" INNER JOIN "account_users" ON "accounts"."id" = "account_users"."account_id" WHERE "account_users"."user_id" = $1 AND "accounts"."id" != $2 LIMIT $3  [["user_id", 1], ["id", 1], ["LIMIT", 1]]
  ↳ app/views/shared/_navbar.html.erb:75
  Rendered shared/_navbar.html.erb (Duration: 17.8ms | Allocations: 7891)
  Rendered shared/_footer.html.erb (Duration: 2.9ms | Allocations: 1392)
  Rendered layout layouts/application.html.erb (Duration: 30.6ms | Allocations: 14682)
Completed 422 Unprocessable Entity in 50ms (Views: 29.6ms | ActiveRecord: 5.0ms | Allocations: 23005)

[ActionCable] [User 1] [Account 1] Unsubscribing from channel: {"channel":"NotificationChannel"}
[ActionCable] [User 1] [Account 1] NotificationChannel stopped streaming from notification:Z2lkOi8vanVtcHN0YXJ0LWFwcC9Vc2VyLzE
[ActionCable] [User 1] [Account 1] NotificationChannel is transmitting the subscription confirmation
[ActionCable] [User 1] [Account 1] NotificationChannel is streaming from notification:Z2lkOi8vanVtcHN0YXJ0LWFwcC9Vc2VyLzE
2fjabf4q

2fjabf4q1#

我明白了。问题是,我在确认身份。但是status是布尔值,默认设置为false。

相关问题