Implementing ancestry on a nested resource throwing an error - ruby-on-rails

I am implementing ancestry on a nested resource.
resources :loads do
resources :messages
end
Here is my index action
def index
load = Load.find(params[:load_id])
#messages = load.messages.scoped
#message = load.messages.new
end
My index.html.erb is throwing the following error.
Missing partial messages/message with {:locale=>[:en],
:formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in:
* "C:/Sites/final/cloud/app/views"
My index.html.erb is as follow
<% title "Messages" %>
<%= nested_messages #messages.arrange(:order => :created_at) %>
<%= render "form" %>
Here is my nested_message definition
module MessagesHelper
def nested_messages(messages)
messages.map do |message, sub_messages|
render(message) + content_tag(:div, nested_messages(sub_messages), :class => "nested_messages")
end.join.html_safe
end
end
Here is my _message.html.erb
<div class="message">
<div class="created_at"><%= message.created_at.strftime("%B %d, %Y") %></div>
<div class="content">
<%= link_to message.content, message %>
</div>
<div class="actions">
<%= link_to "Reply", new_load_message_url(:parent_id => message) %> |
<%= link_to "Destroy", [message.load, message], :confirm => "Are you sure?", :method => :delete %>
</div>
</div>
Any help appreciated.

This error states that your application has tried to search for a partial _messages.html.erb, as a result of this the partial must not be in your /app/views/messages which results in the message you are being shown. Check your messages directory and check if you have this partial. Going by your nested resources I am guessing your association between Load and Message is:
class Load < ActiveRecord::Base
has_many :messages
end
class Message < ActiveRecord::Base
belongs_to :load
end
Further more I noticed that you have the following line in your index action: #message = load.messages.new surely this does not seem right. Because what your telling your application to do is when the controller recieves a response to render the index action it should also create message by doing #message = load.messages.new which is why it is trying to render the partial.
To clarify things a bit more for you. If in your application you had a link_to to create a new user. Upon clicking the new user it will do something like:
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user }
end
end
And will render `app/views/users/new.html.erb which inside this will most probably have a
<%= form_for #user do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<% end %>
This will call your partial which in normal cases would be _form.html.erb. The create action of a particular controller will come into play when you attempt to save the partial. Usually a create block for a controller will look like this:
def create
#title = "Create a user"
#user = User.new(params[:user])
if #user.save
redirect_to usermanagement_path
flash[:success] = "Created successfully."
else
#title = "Create a user"
render 'new'
end
end
Here inside the create action when your _form.html.erb or _message.html.erb is submitted it will try to create a new user by passing in the user through the params. I do thoroughly believe that your issue may potentially well be:
1) Your missing your _message.html.erb
2) Also you are calling a .new inside your index action.
Hope this clears this up for you.

Related

Rails polymorphic comments ajax - 500 (Internal Server Error)

I used this tutorial for making polymorphic comments
https://gorails.com/episodes/comments-with-polymorphic-associations
It works fine but when I set remote true to my comments form I got 505 error(the new comment is not appended to the list) when trying to add a new comment.
But when I reload the page the new comment appears in the list.
What can be wrong here?
I got this files in views/comments folder:
create.js
<% unless #comment.errors.any? %>
$("ul.comments").append('<%= j render "comments/comment" %>')
$("#new_comment")[0].reset();
<% end %>
_form.html.erb
<%= simple_form_for([commentable, Comment.new], remote: true) do |f| %>
<%= f.input :body, label: false %>
<%= f.button :submit, "Submit" %>
<% end %>
comments_controller.rb
def create
#comment = #commentable.comments.new(comment_params)
#comment.user = current_user
#comment.save
respond_to do |format|
format.html { redirect_to #commentable, notice: "Your comment was successfully added."}
format.js
end
end
_comment.html.erb
<li class="comment">
<b><%= comment.user.try(:username) %>:</b>
<%= comment.body%>
</li>
console
UP
I got this routes for post
resources :posts do
resources :comments, module: :posts
end
+
controllers/posts/comments_controller
class Posts::CommentsController < CommentsController
before_action :set_commentable
private
def set_commentable
#commentable = Post.friendly.find(params[:post_id])
end
end
The folder structure looks almost the same as here
https://github.com/excid3/gorails-episode-36/tree/master/app/controllers
the response tab shows this
undefined local variable or method `comment' for #<#<Class:0x007f993d3c5450>:0x007f99450a6190>
Trace of template inclusion: app/views/comments/create.js.erb
and when I replace
<%= j render #comment %> with some text it appends to the list on submit
ok the problem is with _comment.html erb
updated create.js with instance variable for comment and it works now.
<% unless #comment.errors.any? %>
$("ul.comments").append('<%= j render partial: "comments/comment", locals:{comment: #comment} %>')
$("#new_comment")[0].reset();
<% end %>

Values not saving and showing on index page in rail app

New to rails so I am implementing a basic app.
Text field and a submit button, on clicking the submit button the text to be displayed on the div placed below the submit button of the index page.
Code and things I trying is as follows -
Siteurl - http://localhost:3000/lists/index
list controller code -
class ListsController < ApplicationController
def index
List.all
end
def add
#message = params[:todo_text]
List.create(:title => #message)
redirect_to '/lists/index', :notice => "Notice"
end
end
Model list.rb -
class List < ActiveRecord::Base
attr_accessible :title
end
Views list index.html.erb code -
<div id="search">
<%= form_tag("/lists/add", :method=>"post") do %>
<%= text_field_tag(:todo_text, '',:class=>"formtext" ) %>
<%= submit_tag("Add Message", :class=>"submit") %>
<% end %>
</div>
Now when I submit some text it redirects to the same..but data is not reverting back to the page. Let me know what I am doing wrong and how do i fix it ?
in controller
def index
#lists = List.all
end
in index.html.erb
<% #lists.each do |list| %>
...
<% end %>
try
<%= form_for #list, :url => { :action => "add" } do |f| %>
controller
def index
#lists = List.all
end
def add
#list = List.new(params[:title])
redirect_to #lists, :notice => "Notice"
end

Update attribute on a has_many relationship

I am printing a list of user's contacts and want to give the user the ability to mark each contact as "done". (Essentially marking them off their to do list).
How do I update the :done attribute for the specific contact?
This is form with a hidden field is not working:
<% if current_user.contacts.any? %>
<% current_user.contacts.each do |c| %>
<li id="<%= c.id %>">
<%= c.name %><br/>
<%= form_for(#contact) do |f| %>
<%= f.hidden_field :done, :value=>true %>
<%= f.submit "Mark as done", class: "btn btn-small btn-link"%>
<% end %>
</li>
<% end %>
I get this error:
Template is missing Missing template contacts/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "C:/Sites/rails_projects/sample_app/app/views"
This is my contacts controller:
def create
#contact = current_user.contacts.build(params[:contact])
if #contact.save
flash[:success] = "Contact saved!"
redirect_to root_url
else
flash[:error] = "Something is wrong"
end
end
For some reason, perhaps due to validation rules, the #contact object can't be saved.
In this case, the else branch in your create action doesn't specify what to render, so it's looking for a create template. You may be able to simply add a line to render :action => :new or redirect_to :action => :new, assuming your new action doesn't require preloading additional data.
else
flash[:error] = "Something is wrong"
redirect_to :action => :new
end
You can also use respond_with instead of explicitly redirecting, which will render the new action if errors were found:
def create
#contact = current_user.contacts.build(params[:contact])
if #contact.save
flash[:success] = "Contact saved!"
else
flash[:error] = "Something is wrong"
end
respond_with #contact, :location => root_url
end

undefined method `errors' for nil:NilClass

Here is my Edited details:
I have my controller like,
class Enr::Rds::SurvRdsapXrefsController < Enr::Controller
def index
#enr_rds_surv_rdsap_xrefs = Enr::Rds::SurvRdsapXref.paginate(page: params[:page])
end
def show
end
def new
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
def edit
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.find(params[:id])
end
def create
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new(params[:enr_rds_surv_rdsap_xref])
respond_to do |format|
if #enr_rds_surv_rdsap_xref.save
format.html { redirect_to :enr_rds_surv_rdsap_xrefs, notice: "Survey link was successfully created." }
format.js
format.json { render json: #enr_rds_surv_rdsap_xref, status: :created, location: #enr_rds_surv_rdsap_xref }
else
format.html { render action: "new" }
format.js
format.json { render json: #enr_rds_surv_rdsap_xref.errors, status: :unprocessable_entity }
end
end
end
def update
end
def destroy
end
end
Here is my view form like
<%= form_for(#enr_rds_surv_rdsap_xref, :remote => true) do |f| %>
<% if #enr_rds_surv_rdsap_xref.errors.any? %>
<div id="error_explanation">
<div class="validate">
The form contains <%= pluralize#enr_rds_surv_rdsap_xref.errors.count, "error") %>.
</div>
<ul>
<% #enr_rds_surv_rdsap_xref.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="control-group">
<%= f.label :section %><br />
<%= f.text_field :section %>
</div>
<%= f.submit %>
<% end %>
When i click the index page to create a new link, the index page showing error like
NoMethodError in Enr/rds/surv_rdsap_xrefs#index
undefined method `errors' for nil:NilClass
Thanks for the suppport and please suggest me to rectify the error. I am new to ROR. Thanks
Your error reveals that the rendering of the index template is causing the error, which means you're rendering the form for the new survey (the code snippet above) in the index template. This is fine, but if you're going to do that, you'll have to instantiate a new survey in index, as well as in new.
At the simplest, you could just copy the code in new to index:
def index
#enr_rds_surv_rdsap_xrefs = Enr::Rds::SurvRdsapXref.paginate(page: params[:page])
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
def new
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
To keep your code a bit DRYer you might change where the new instance is created. A pattern you'll often see is something similar to:
before_filter :build_record, :only => [:new, :index]
protected
def build_record
#survey = YourSurvey.new
end
This way you don't even need to write the new/index methods if you don't have any other logic.
Do you also set #survey in the new action in your controller? The error means that when the view is rendered #survey is nil, so there must be a problem with setting that instance variable.
Do you get the error when you go to the 'new' view or when you try to submit the form (create)?
The form contains <%= pluralize#enr_rds_surv_rdsap_xref.errors.count, "error") %>
This line of the code is the problem. You are lacking a "(" between the pluralize and the #enr...
Explained: RoR thinks that the object is: pluralize#enr... instead of the # All alone, and he has no errors for this kind of object.

how to catch mongoid validation erros from another controller?

I have 2 controllers: DocumentsController and DashboardController
After the user login successful, he is redirected to dashboard_path, which has a form to create a 'fast document' like this
<%= form_for #document, :html => {:class => 'well'} do |f| %>
<% if #document.errors.any? %>
<div id="alert alert-block">
<div class="alert alert-error">
<h2>Couldn't create your doc. :(</h2>
<ul>
<% #document.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
</div>
<% end %>
<label>A lot of fields</label>
<%= f.text_field :fields %>
<div class="form-actions">
<%= f.submit 'Create document', :class => 'btn btn-large' %>
</div>
<% end %>
but when an exception happen (like the user forgot to fill a field), I would like to show these exceptions, not just an alert saying 'Error'...actually, I didn't found a way to do this
here's my DashboarController
class DashboardController < ApplicationController
before_filter :authenticate
def index
#document = Document.new
end
end
and my DocumentsController
class DocumentsController < ApplicationController
respond_to :json, :html
def show
end
def create
#document = Document.new(params[:document])
#document.user = current_user
if #document.save
redirect_to dashboard_path, notice: 'Created!'
else
flash[:error] = 'Error!'
redirect_to dashboard_path
end
end
end
any help is appreciated :)
You are correctly redirecting on success; on failure, though, should not redirect; you need to render the template where the form was filled.
if #document.save
redirect_to dashboard_path, notice: 'Created!'
else
render 'dashboard/index'
end
You'll have to make sure that any variables needed by the index template are available in the create action of the documents_controller (you're just rendering the index template; you're not running the code from the dashboard controller's index action). Here's a excerpt from the relevant Rails Guide to clarify:
Using render with :action is a frequent source of confusion for Rails newcomers. The specified action is used to determine which view to render, but Rails does not run any of the code for that action in the controller. Any instance variables that you require in the view must be set up in the current action before calling render.
More at http://guides.rubyonrails.org/layouts_and_rendering.html#using-render

Resources