Search code examples
ruby-on-railssimple-form-for

Simple Form for - Nested Resources paths


I'm trying to make an app in Rails 5 for post answer to the task.

The Task content and the answer form in the same page.

When the user come into the task page, he can see the task content.

And he can post(create) an answer or edit the answer.

I get an error:

NoMethodError in Tasks#show undefined method `to_key' for # Did you mean? to_query to_set to_ary

What am I doing wrong? What else information do you need that can help debug this issue?

I'd really apprieciate any help!


Models

```

# task.rb



class Task < ApplicationRecord
 belongs_to :post
 has_many :answers, dependent: :destroy

end

# answer.rb

class Answer < ApplicationRecord
 belongs_to :task
 belongs_to :user
end

```

routes.rb

```

resources :tasks, only: [:show] do
 resources :answers #, only: [:new, :create, :edit, :update]

end

```

Controllers

```

# tasks_controller.rb

class TasksController < ApplicationController
  before_action :authenticate_user!, only: [:show]

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

    if @task.answers.present?
      @answer = Answer.where("task_id = ? and user_id = ?", @task.id, current_user.id)
    else
      @answer = Answer.new
    end
  end


 end


# answers_controller.rb

def new
  @task = Task.find(params[:task_id])
  @answer = Answer.new
end

def create
  @task = Task.find(params[:task_id])
  @answer = Answer.new(answer_params)
  @answer.task_id = @task.id
  @answer.user_id = current_user.id

  if @answer.save
    redirect_to post_path(@task.post), notice: "Answer Added."
  else
    render :new
  end

end

```

Views

```

<div class="answer-form">
<%= simple_form_for [@task, @answer], :url => task_answer_path(@task, @answer), method: :put  do |f| %>
  <% if @task.answers.present? %>
   <%= f.input :content, id: "x", value: @task.answers.first.content,
               input_html: {class: "hidden"}, name: "content", label: false %>
   <trix-editor input="x" class="formatted_content trix-content"></trix-editor>

   <div class="form-actions">
     <%= f.submit "Submitting", class: "assignment-btn", data: {disable_with: "Submitting..."} %>
   </div>
<% end %>

<% else %>

   <%= simple_form_for [@task, @answer], :url => task_answers_path(@task), method: :post do |f| %>
                <%= f.input :content, id: "x", value: "content",
                            input_html: {class: "hidden"}, name: "content", label: false %>
                <trix-editor input="x" class="formatted_content trix-content"></trix-editor>

                <div class="file-upload-block">
                    <input name="fileToUpload[]" id="fileToUpload" type="file">
                </div>

                <div class="form-actions">
                  <%= f.submit "提交", class: "assignment-btn", data: {disable_with: "Submitting..."} %>
                </div>
               <% end %>


<% end %>
</div>

```


Solution

  • I know what may be wrong, the line below was returning an ActiveRecord::Relation, not the instance itself, you need to append 'first' in the end of the answer query, like such:

     @answer = Answer.where(task: @task, user: current_user).first