peterbie
peterbie

Reputation: 5

submit using hidden field

My problem is connected with my previous problem. It was solved by using nested routing. But there was different idea without using nested resources. I tried it as an exercise. But when I submit data, ActiveRecord::RecordNotFound in SentencesController#create shows up.

Rails.application.routes.draw do
    root 'stories#index'
    get 'stories/show'
  get 'stories/new'
  post 'stories/:story_id', to: 'sentences#create'
  resources :stories
  resources :sentences, only: [:create] 
end

shared/_sentence_form.html.erb is part of story/show_form.html.erb

<%= form_for(@sentence) do |f| %>
  <%= hidden_field_tag :story_id, value: @story.id %>
  <%= f.text_area :content, placeholder: "Compose new sentence..." %>
  <%= f.submit "Save"%>
<% end %>

SentencesController

class SentencesController < ApplicationController
    before_action :sentence_params
    before_action :find_story

    def create
        @sentence = find_story.sentences.build(sentence_params)
    if @sentence.save
      flash[:success] = "You wrote the continuation!"
      redirect_to root_url
    else
        flash[:danger] = "I did not save your words!"
        redirect_to "#"
    end
  end

  private

    def sentence_params
      params.permit(:content, :story_id)
    end

    def find_story
        @story = Story.find(params[:story_id])
    end
end

and model:

class Sentence < ApplicationRecord
  belongs_to :story
  validates :story_id, presence: true
  validates :content, presence: true, length: { maximum: 150 }
end

I tried many combinations in controller and view. When I put some information in the text_area and click submit they don't save.

Upvotes: 0

Views: 55

Answers (2)

max
max

Reputation: 102240

The param is nested:

def find_story
  @story = Story.find(params[:sentance][:story_id])
end

But nesting the route is a better RESTful design anyways.

The route POST /stories/:story_id/sentances makes it very clear what the action does.

resources :stories do
  resources :sentences, only: [:create] 
end

<%= form_for([@story, @sentence]) do |f| %>
  <%= f.text_area :content, placeholder: "Compose new sentence..." %>
  <%= f.submit "Save"%>
<% end %>

This will properly pass params[:story_id] as a segment of the URL.

Upvotes: 1

Holger Frohloff
Holger Frohloff

Reputation: 1705

I am not sure that's a solution to your problem, but I believe that

def sentence_params
  params.permit(:content, :story_id)
end

needs a :sentence in there somewhere. Your form is a form_for @sentence so I guess your params are params[:sentence][:content] or similar.

I believe your error happens in the line @story = Story.find(params[:story_id]), right? Make sure that the @story variable is present in your form and that the record can be found.

Upvotes: 0

Related Questions