0

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.

3
  • What do your submitted params look like? Perhaps this: hidden_field_tag :story_id, value: @story.id should be this: hidden_field_tag :story_id, @story.id Commented Mar 23, 2018 at 21:22
  • I don't really see why you're trying the worst possible way to solve the problem though when you already have an answer which shows the rails way to handle it gracefully. Commented Mar 23, 2018 at 21:30
  • @max As I wrote this is an exercise. I'm Rails beginner and I'm experimenting a bit to get along with Ruby (on Rails). Thanks for advice to keep REST designing. Commented Mar 23, 2018 at 21:45

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

In rails 5 validates :story_id, presence: true is totally superflous as belongs_to associations are non-optional by default.
I'd say the hidden_field_tag is superfluous in the form, since the story_id is already given in the url, right?
@HolgerFrohloff, yes it was just a copy-paste omission.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.