簡體   English   中英

在Rails控制台中工作,但得到:“ Workouts#index中的NoMethodError(nil:NilClass的未定義方法'movements')”

[英]Working in rails console but getting : “NoMethodError in Workouts#index (undefined method `movements' for nil:NilClass)”

我一直在這些論壇上搜索過去2天,最終放棄了。 我一直在開發Rails應用程序,您可以在其中上傳鍛煉,然后讓其他人查看鍛煉並下載任何附加的excel文件。 我的表格看起來像這樣

  '<div class="form-group">
     <div class="control-label col-md-2">
                <%= f.label :name, "Workout name" %><br>
              </div>
              <div class="col-md-10">
                <%= f.text_field :name, class: "form-control" %>
              </div>
            </div>
            <div class="form-group">
              <div class="control-label col-md-2">
                <%= f.label :summary, "Summary", placeholder: "Who's this for? what experience level? Athletes or Bodybuilders etc"  %>
              </div>
              <div class="col-md-10">
                <%= f.text_area :summary, class: "form-control", rows: 10%>
              </div>
            </div>
          <div class="clearfix">
            <div class="col-lg-3 col-md-6">
            <%= f.label :Movement %>
              <%= f.fields_for :movements do |movement| %>
                <%= render 'movement_fields', f: movement %>
            <% end %>
                <div class="links">
                  <%= link_to_add_association 'Add movement', f, :movements, class: "pull-right d-inline-block btn btn-primary add-button" %>
                  </br>
                  </br>
                </div>
            </div>
            <div class="col-lg-3 col-md-6">
                 <%= f.label :Reps %>
                    <%= f.fields_for :reps do |rep| %>
                      <%= render 'rep_fields', f: rep %>
                    <% end %>
                <div class="links">
                  <%= link_to_add_association 'Add Reps', f, :reps, class: "pull-right d-inline-block btn btn-primary add-button" %>
                </br>
                </br>
                </div>
            </div>
            <div class="col-lg-3 col-md-6">
            <%= f.label :Sets %>
                    <%= f.fields_for :zets do |zet| %>
                      <%= render 'zet_fields', f: zet %>
                    <% end %>
                <div class="links">
                  <%= link_to_add_association 'Add Set', f, :zets, class: "pull-right d-inline-block btn btn-primary add-button" %>
                </div>
                  </br>
                  </br>
            </div>
            <div class="col-lg-3 col-md-6">
                 <%= f.label :Weights %>
                    <%= f.fields_for :weights do |weight| %>
                      <%= render 'weight_fields', f: weight %>
                    <% end %>
                <div class="links">
                  <%= link_to_add_association 'Add weight', f, :weights, class: "pull-right d-inline-block btn btn-primary add-button" %>
                </div>
                  </br>
                  </br> 
            </div>
            <strong>Upload image: </strong>
                <span class="picture">
                    <%= f.file_field :attachment %>
                </span>
          </div>

            <div class="form-group">
              <div class="col-md-offset-2 col-md-10">
                <%= f.submit class: "btn btn-success btn-lg" %>
              </div>
            </div>
          <% end %>
        </div>
      </div>
    </div>`

這似乎將我需要的所有內容上載到數據庫,因為當我瀏覽條目時,似乎有我需要的數據,即,execution_id附加到運動等上。

這是schema.rb

# Deleted some other columns in this that are in the app that aren't relevant to the post to reduce the amount of text. Exercises column is from another element in the app that works that i used basically the exact same method in creating. 

ActiveRecord::Schema.define(version: 20161113011850) do


  create_table "exercises", force: :cascade do |t|
    t.integer  "duration_in_min"
    t.text     "workout"
    t.date     "workout_date"
    t.integer  "user_id"
    t.datetime "created_at",      null: false
    t.datetime "updated_at",      null: false
  end

  add_index "exercises", ["user_id"], name: "index_exercises_on_user_id"

  create_table "movements", force: :cascade do |t|
    t.string   "name"
    t.integer  "exercise_id"
    t.integer  "workout_id"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.integer  "workout_id"
  end

  add_index "movements", ["exercise_id"], name: "index_movements_on_exercise_id"
  add_index "movements", ["workout_id"], name: "index_movements_on_workout_id"


  create_table "reps", force: :cascade do |t|
    t.integer  "amount"
    t.integer  "exercise_id"
    t.integer  "workout_id"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

  add_index "reps", ["exercise_id"], name: "index_reps_on_exercise_id"
  add_index "reps", ["workout_id"], name: "index_reps_on_workout_id"

  create_table "reviews", force: :cascade do |t|
    t.text     "body"
    t.integer  "user_id"
    t.integer  "recipe_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "users", force: :cascade do |t|
    t.string   "username"
    t.string   "email",                  default: "",    null: false
    t.string   "encrypted_password",     default: "",    null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,     null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                             null: false
    t.datetime "updated_at",                             null: false
    t.string   "first_name"
    t.string   "last_name"
    t.boolean  "admin",                  default: false
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

  create_table "weights", force: :cascade do |t|
    t.integer  "kilogram"
    t.integer  "workout_id"
    t.integer  "exercise_id"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

  add_index "weights", ["exercise_id"], name: "index_weights_on_exercise_id"
  add_index "weights", ["workout_id"], name: "index_weights_on_workout_id"

  create_table "workouts", force: :cascade do |t|
    t.string   "name"
    t.text     "summary"
    t.integer  "user_id"
    t.string   "attachment"
    t.datetime "created_at",      null: false
    t.datetime "updated_at",      null: false
    t.integer  "duration_in_min"
  end

  create_table "zets", force: :cascade do |t|
    t.integer  "quantity"
    t.integer  "exercise_id"
    t.integer  "workout_id"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

  add_index "zets", ["exercise_id"], name: "index_zets_on_exercise_id"
  add_index "zets", ["workout_id"], name: "index_zets_on_workout_id"

end

還有模型exercise.rb

類Workout <ActiveRecord :: Base所屬於:user mount_uploader:attachment,AttachmentUploader

  has_many :movements
  has_many :reps
  has_many :zets
  has_many :weights  

  accepts_nested_attributes_for :movements,
                                                            reject_if: proc { |attributes| attributes['name'].blank? },
                                                            allow_destroy: true
    accepts_nested_attributes_for :reps,
                                                            reject_if: proc { |attributes| attributes['amount'].blank? },
                                                            allow_destroy: true
  accepts_nested_attributes_for :zets,
                                                            reject_if: proc { |attributes| attributes['quantity'].blank? },
                                                            allow_destroy: true
    accepts_nested_attributes_for :weights,
                                                            reject_if: proc { |attributes| attributes['kilogram'].blank? },
                                                            allow_destroy: true

  validates :name, presence: true
  validates :summary, presence: true
  validates :movements, presence: true
  validates :reps, presence: true
  validates :zets, presence: true
  validates :weights, presence: true
end

和控制器exercises_controller.rb

 class WorkoutsController < ApplicationController
      before_action :set_workout, only: [:edit, :update, :show, :like, :review]
      before_action :authenticate_user!, except: [:show, :index, :like, :search]
      before_action :require_same_user, only: [:edit, :update]
      before_action :admin_user, only: :destroy

  def index
    @workouts = Workout.all
  end

  def show
    @random_workout = Workout.where.not(id: @workout).order("RANDOM()").first(3)
  end

  def new
    @workout = Workout.new
  end

  def create
    @workout = Workout.new(workout_params)
    @workout.user = current_user

    if @workout.save
      flash[:success] = "Your workout was created successfully!"
      redirect_to workouts_path
    else
      render :new
    end
  end

  def edit

  end

  def update
    if @workout.update(workout_params)
      flash[:success] = "Your workout was update success"
      redirect_to workout_path(@workout)
    else
      render :edit
    end
  end

  def destroy
    Workout.find(params[:id]).destroy
    flash[:success] = "Workout Deleted"
    redirect_to workouts_path
  end

  def review
    review = Review.create(body: params[:body], user: current_user, workout: @workout)
    if review.valid?
      flash[:success] = "Thank you for reviewing this workout"
    else
      flash[:danger] = "Review failed to post"
    end
    redirect_to :back
  end

  def deletereview
    Review.find(params[:revid]).destroy
    flash[:success] = "Review deleted"
    redirect_to :back
  end

  private

    def workout_params
        params.require(:workout).permit(:name, :summary, :attachment, :user_id, movements_attributes: [:id, :name, :_destroy], reps_attributes: [:id, :amount, :_destroy], zets_attributes: [:id, :quantity, :_destroy], weights_attributes: [:id, :kilogram, :_destroy],)
    end

    def set_workout
      @workout = Workout.find(params[:id])
    end

    def require_same_user
      if current_user != @recipe.user and !current_user.admin?
        flash[:danger] = "You can only edit your own recipes"
        redirect_to recipes_path
      end
    end


    def admin_user
      redirect_to recipes_path unless current_user.admin?
    end

end

最后是index.html.erb

  <thead>
    <tr>
      <th>Name</th>
      <th>Summary</th>
      <th>Attachment</th>
      <th>Exercises</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @workouts.each do |workout| %>
      <tr>
        <td><%= workout.name %></td>
        <td><%= truncate(workout.summary, length: 350) %><%= link_to 'click to see workout', workout_path(workout)%></td>
        <td><%= link_to "Download Workout", workout.attachment_url %>%></td>
        <td><%= link_to 'Show', workout %></td>
    <% end %>
    <% @workout.movements.each do |movement| %>
        <td>
          <ol>
            <li>
              <%= movement.name %>
            </li>
          </ol>
    <%end%>
    <% @workout.reps.each do |rep| %>
        <td>
          <ol>
            <li>
              <%= rep.amount %>
            </li>
          </ol>
    <%end%>

對不起所有文本,我只是想在第一輪就包括所有內容。 我知道這個問題已被處死,因此我很抱歉,因為無法從已經回答的問題中解決問題,但是我確實希望弄清楚為什么我會收到此錯誤。

在Workouts#index中顯示NoMethodError,顯示/home/ubuntu/workspace/app/views/workouts/index.html.erb,其中第24行出現:

nil:NilClass的未定義方法“運動”

正如我提到的,我現在在應用程序中的其他2個功能上實現了幾乎完全相同的功能兩次,其工作原理與“應有的功能”幾乎完全相同。 所以我很困惑:(

由於未聲明變量@workout因此您將獲得未定義的方法-這意味着@workout為nil,並且您正在嘗試對該nil對象調用movements

你有一個變量@workouts但我假設是不是你想要的對象......我想你想使用workout作為申報@workout.each |workout| 這導致了第二個問題。 您在結束了塊嘗試使用之前@workout (應該是workout

這是您所擁有的:

<% @workouts.each do |workout| %>
   # do stuff
<% end %>
# variable workout now out of scope
<% @workout.movements.each do |movement| %>

你應該做的就是改變實例變量@workout局部變量workout ,並在你的每一塊嵌入此。

<% @workouts.each do |workout| %>
   # do stuff with workout object here
  <% workout.movements.each do |movement| %>
    # do stuff with movement object here
  <% end %>
  <% workout.reps.each do |rep| %>
    # do stuff with rep object here
  <% end %>
  #etc ... etc...
<% end %>

您試圖在@workout變量上調用移動關聯,因為您尚未在控制器操作中聲明任何位置。 因此,不會引發方法錯誤異常。 如果要循環進行每種鍛煉的動作,則需要進入循環並在其上調用關聯。

<% @workouts.each do |workout| %>
   <% workout.movements.each do |movement| %>
     <%= movement.name %>
   <% end %>
 <% end %>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM