Home > ruby on rails > Creating nested models in Rails 4 forum app

Creating nested models in Rails 4 forum app

January 31Hits:7
Advertisement

Hello I am making a Forum application in Rails 4. It can have numerous forums, each with numerous topics. Each topic can have many posts. When creating a new topic, one must also create the initial post, much like Stack Overflow itself. Therefore, I have a text area in the "New Topic" form that allows this with a fields_for method. The Problem is, when you click the "Create Topic" button after filling out the form (including the "post" field), the transaction is rolled back. The following validation error appears:

3 errors prohibited this topic from being saved:

  • Posts forum must exist
  • Posts topic must exist
  • Posts user must exist

This is my form: app/views/topics/_form.html.erb

<%= form_for([ @forum, topic ]) do |f| %>   <% if topic.errors.any? %>     <div id="error_explanation">       <h2><%= pluralize(topic.errors.count, "error") %> prohibited this topic from being saved:</h2>        <ul>       <% topic.errors.full_messages.each do |message| %>         <li><%= message %></li>       <% end %>       </ul>     </div>   <% end %>    <div class="field">     <%= f.label :title %><br>     <%= f.text_field :title %>   </div>    <div class="field">     <%= f.fields_for :posts do |builder| %>       <%= builder.label :content %><br>       <%= builder.cktext_area :content, class: 'ckeditor' %>     <% end %>   </div>    <div class="actions">        <%= f.submit 'Create Topic', class: "btn btn-l btn-success" %>   </div> <% end %> 

Models: forum.rb

class Forum < ApplicationRecord     has_many :topics, dependent: :destroy     has_many :posts, through: :topics      def most_recent_post       topic = Topic.last       return topic     end end 

topic.rb

class Topic < ApplicationRecord   belongs_to :forum   belongs_to :user    has_many :posts, dependent: :destroy   accepts_nested_attributes_for :posts  end 

post.rb

class Post < ApplicationRecord   belongs_to :forum   belongs_to :topic   belongs_to :user    validates :content, presence: true end 

The controller for topics, app/controllers/topics_controller.rb

class TopicsController < ApplicationController   before_action :get_forum   before_action :set_topic, only: [:show, :edit, :update, :destroy]    # GET /topics   # GET /topics.json   def index     @topics = @forum.topics   end    # GET /topics/1   # GET /topics/1.json   def show   end    # GET /topics/new   def new     @topic = @forum.topics.build     @topic.posts.build   end    # GET /topics/1/edit   def edit     # @topic.posts.build   end    # POST /topics   # POST /topics.json   def create     @topic = @forum.topics.build(topic_params.merge(user_id: current_user.id))     @topic.last_poster_id = @topic.user_id      respond_to do |format|       if @topic.save         format.html { redirect_to forum_topic_path(@forum, @topic), notice: 'Topic was successfully created.' }         format.json { render :show, status: :created, location: @topic }       else         format.html { render :new }         format.json { render json: @topic.errors, status: :unprocessable_entity }       end     end   end    # PATCH/PUT /topics/1   # PATCH/PUT /topics/1.json   def update     respond_to do |format|       if @topic.update(topic_params)         format.html { redirect_to forum_topic_path(@forum, @topic), notice: 'Topic was successfully updated.' }         format.json { render :show, status: :ok, location: @topic }       else         format.html { render :edit }         format.json { render json: @topic.errors, status: :unprocessable_entity }       end     end   end    # DELETE /topics/1   # DELETE /topics/1.json   def destroy     @topic.destroy     respond_to do |format|       format.html { redirect_to forum_path(@forum), notice: 'Topic was successfully destroyed.' }       format.json { head :no_content }     end   end    private     # Use callbacks to share common setup or constraints between actions.     def get_forum       @forum = Forum.find(params[:forum_id])     end      def set_topic       @topic = Topic.find(params[:id])     end      # Never trust parameters from the scary internet, only allow the white list through.     def topic_params       params.require(:topic).permit(:title, :last_poster_id, :last_post_at, :tags, :forum_id, :user_id, posts_attributes: [:id, :content])     end end 

As you see I've added the posts_attributes to the strong parameters for topic. These are the only fields that posts have besides the foreign key references (:forum_id, :topic_id, :user_id). And I've tried putting those attributes in, but I get the same error.

Finally, this is my routes.rb

Rails.application.routes.draw do    resources :forums do     resources :topics do       resources :posts     end   end   resources :sessions   resources :users   mount Ckeditor::Engine => '/ckeditor' end 

I should also mention that I have tried adding hidden_fields inside of fields_for, with the id criteria for @forum, @topic, and current_user. That throws the same validation error.

What am I missing? I feel like it's something in the controller. Like I'm not saving it properly. Every tutorial I've seen has it this way. Except for the Rails <=3 versions, which are way different because of no strong_params.

Any ideas? Thanks for the help!

EDIT Here is the log output when I try to submit a topic entitled "I am a title" and the content "I am some content"...

Started POST "/forums/1/topics" for 127.0.0.1 at 2016-01-31 09:03:33 -0500 Processing by TopicsController#create as HTML   Parameters: {"utf8"=>"✓", "authenticity_token"=>"pYt842XQHiOKqNjPHBO8lNP2z92gHF7Lpt24CppbuvHR/cFHky3FVCpBs77p7WFRKmYBHgeZQjx0sE+DI+Q+sQ==", "topic"=>{"title"=>"I am a title", "posts_attributes"=>{"0"=>{"content"=>"<p>I am some content</p>\r\n"}}}, "commit"=>"Create Topic", "forum_id"=>"1"}   Forum Load (0.6ms)  SELECT  "forums".* FROM "forums" WHERE "forums"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]   User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]    (0.3ms)  BEGIN   CACHE (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]    (0.4ms)  ROLLBACK 

Answers

This is not a direct answer; too long for comment.

One of the issues you have with your routes is that you're nesting too many resources:

Resources should never be nested more than 1 level deep...

resources :x do
  resources :y
end

--

Although you can do what you're doing, it would perhaps be better to use a scope:

#config/routes.rb
scope ':forum' do
   resources :topics do
      resources :posts
   end
end

The issue you're facing is that things can get very complicated, very quickly. Although the

This way, you could make the forums CRUD accessible in its own set of functionality:

#config/routes.rb
resources :forums #-> only accessible to admins?
scope ...

Either way, you'd still need to define your routes with the forum present:

<%= link_to "Test", [@forum, @topic, @post] %>

Related Articles

  • Creating nested models in Rails 4 forum appJanuary 31

    Hello I am making a Forum application in Rails 4. It can have numerous forums, each with numerous topics. Each topic can have many posts. When creating a new topic, one must also create the initial post, much like Stack Overflow itself. Therefore, I

  • form validation with nested models in Rails

    form validation with nested models in RailsJanuary 22

    I have this problem. I need to validate the attributes of two models in the same form in Rails. One is the parent of the other. The form is like this: <%= semantic_form_for @professional do |pro| %> <%= pro.inputs :id => "information"

  • Rails - Why does my nested model form not require 'accepts_nested_attributes_for'February 9

    I have two models item and user_item. Item has many user_items and user_items belongs to item. I have a form where a user can create a new item. In the form a user should include a picture. The name, description, and tags get saved to a new item obje

  • Rails routes for self nested modelsJanuary 15

    In my rails app I have a Task model. In my app, my tasks can have substasks and so on. Since my subtasks are tasks with only a parent task, I did a self-nested model such as class Task < ActiveRecord::Base ## Self Join has_many :subtasks, class_name:

  • Creating Instance of Nested model inside parent controllerJanuary 18

    I would like to know if it is possible to create an instance of a nested model inside the parents controller. Let me explain. I have a model called Museum and another model called Museumimage. Museumimage has only one field which is an attachment, ma

  • Android app to create nested folders on home screenSeptember 1

    I'm looking for an app that can create nested folders on Home screen. For example, Home Screen → some XYZ icons scattered on it → those icons are moved into a folder F1 → this folder is moved into a new folder F2 which already has some ABC icons. Now

  • Rails nested models and virtual attribute initializationJanuary 27

    I have a problem understanding how are attributes "sent" to nested model(s), and if is possible to do this for model with virtual attrubute too. I have three models: class User < ActiveRecord::Base ... has_and_belongs_to_many :clearancegoods

  • rails with most nested models and cocoon gem;

    rails with most nested models and cocoon gem;February 16

    I have a rails4 app with nested model form. There is a product model that has_many product_features, has_many product_usecases and has_many product_competitors. Everything works fine except when I load the page only the first nested model (product_fe

  • Creating Nested Folders via Client Object ModelNovember 15

    I'm trying to create nested folders in my document library so it looks like this: http://site/PublicDocuments/Folder1/Folder2/Folder3/ The document library "Public Documents" exists but none of the folders exist yet. Here's the working code for

  • Nested Comments with Rails

    Nested Comments with RailsMay 1

    Comments are everywhere. Blogs, social networks, fan sites, learning resources – they all have some kind of a commenting system. Often we would like to present our users options to both leave a comment and reply as well. The most natural way to repre

  • Forem - A Rails Forum Engine

    Forem - A Rails Forum EngineJune 9

    Have you ever wanted to set up a forum for your website? There are tons of solutions out there that you can use for this task. However, what about a forum that is integrated directly into your Rails app? One that can be modified the way you want? A w

  • Active Model Serializers, Rails, and JSON! OH MY!

    Active Model Serializers, Rails, and JSON! OH MY!October 19

    JSON (JavaScript Object Notation) is a format that can be used to store or exchange data. It is easy to read by humans and easy to parse by machines, which is why a lot of APIs use JSON. In this article, we will learn how to create custom JSON respon

  • Dynamic nested form in RailsFebruary 8

    I have a Rails 3.2.22 app that I'm maintaining and I need to create a quasi-complex form. It's a form that records medications into a report. So my thought is to build a model called NarcoticUsage to contain the record then an associated/nested Model

  • How to get multiple records for same model with Rails form_forJanuary 20

    I am trying to build a basic recipes app but am having trouble allowing the user to input multiple ingredients for one recipe. The array of permitted params for the ingredients ends up empty. So I guess my question is - how do I permit the array of i

  • Dynamic Collapsible Lists in Rails 4 appJanuary 26

    UPDATE: For anyone who has this problem in the future. I used the CollapsibleList from http://code.stephenmorley.org/javascript/collapsible-lists/. It worked like a charm! Just include it in your app/assets/javascripts folder and add to your .html.er

  • Is it possible to trick ActiveRecord into understanding it has all the data it needs to create related models in memory?February 9

    For a couple of years, I've worked to make a database that holds the data for an incredibly-complicated engineering process. Right now, it's served by an SQL Server database in Azure, with a WinForms (w/ DevExpress) client, and an Azure worker role f

  • PHP MVC class with controller and nested model

    PHP MVC class with controller and nested modelNovember 26

    I had asked a first question about this class a while ago and got a few answers here which made me rewrite it completely. I removed all statics and globals, added my variables as arguments for the constructor, and pass them again as reference through

  • Problem validating parent model with nested models in modelbuilder

    Problem validating parent model with nested models in modelbuilderMarch 24

    I have a parent model with several nested models. I'm having trouble getting the parent model to validate. The issue is with sub model 4. The two screenshots are of the parent model and sub model 4. The output from sub model 3 feeds into parameter "M

  • Can't deploy Ruby 2, Rails 4 app to LinodeMarch 29

    I have a Rails 4 app and I want to deploy it to my Linode and I'm struggling a lot to get this working. I followed all the basic instructions from the Linode guides, also, installed all the dependencies for my app, configured the database, created a

  • How to unit test models in MVC / MVR app?May 29

    I'm building a node.js web app and am trying to do so for the first time in a test driven fashion. I'm using nodeunit for testing, which I find allows me to write tests quickly and painlessly. In this particular app, the heavy lifting primarily invol

Copyright (C) 2017 ceus-now.com, All Rights Reserved. webmaster#ceus-now.com 14 q. 0.851 s.