I would like to set a comment form on a post in the "group message show" view.But I have an error message like,
NoMethodError at /group_messages/64
undefined method `group_message_group_message_comments_path' for #<#:0x007f9c0afa0b38>
Could you give me some advice?
☆show.html.erb(group_messages)
<h2>Add a comment</h2>
<%= form_for([#group_message, #group_message_comment]) do |f| %>
<% if #group_message_comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#group_message_comment.errors.count, "error") %> prohibited this group_message_comment from being saved:</h2>
<ul>
<% #group_message_comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %><%# do%>
</ul>
</div><!-- error_explanation-->
<% end %><%# if any?%>
<div class="field">
<%= f.label :member_id %><br />
<%= f.number_field :member_id %>
</div>
<div class="field">
<%= f.label :gmessage_id %><br />
<%= f.number_field :group_message_id %>
</div>
<div class="field">
<%= f.label :group_id %><br />
<%= f.number_field :group_id %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions" >
<%= f.submit "Comment"%>
</div>
<% end %><%# form_for>
☆group_messages_controller
def show
if !checklogin? then return end
#group_message = GroupMessage.find(params[:id])
#isme = me? #group_message
#group_message_comment = GroupMessageComment.new
#group_message_comment = GroupMessage.find(params[:id]).group_message_comments.build
respond_to do |format|
format.html # show.html.erb
format.json { render json: #group_message }
end
end
☆GroupMessage model
class GroupMessage < ActiveRecord::Base
attr_accessible :content, :member_id, :group_id
belongs_to :member
belongs_to :group
has_many :group_message_comments
end
☆GroupMessageComment model
class GroupMessageComment < ActiveRecord::Base
attr_accessible :content, :gmessage_id, :group_id, :member_id
belongs_to :member
belongs_to :group_message
end
☆routes.rb
MiniSNS::Application.routes.draw do
resources :group_message_comments
root :to => 'members#login'
match '/groups/join'
resources :group_messages
resources :groups do
resources :group_messages
end
match '/members/new'
resources :index
resources :groups
post 'groups/:id' => 'group#show'
post '/groups/new'
post '/index/index'
match '/members/login'
match '/members/logout'
match '/members/friend'
match 'members/show'
post 'messages/comment'
resources :comments
resources :messages
resources :friends
resources :members
That error message is due to the following line of code:
<%= form_for([#group_message, #group_message_comment]) do |f| %>
This is because you haven't set the correct routing for your models. Can you post your routes.rb too so that I can have a look?
I think you need nested routes, something like:
resources :group_messages do
resources :group_message_comment
end
Related
I've followed the Go Rails tutorial below to set up comments with polymorphic associations: https://gorails.com/episodes/comments-with-polymorphic-associations
However, I have a nested situation with two models (movies/parts). It is working with 'movies' but I cannot get it working with child model 'parts'.
Models
class Comment < ApplicationRecord
belongs_to :user
belongs_to :commentable, polymorphic: true
end
class Movie < ApplicationRecord
has_many :parts, dependent: :destroy
has_many :comments, as: :commentable
end
class Part < ApplicationRecord
belongs_to :movie
has_many :comments, as: :commentable
end
config/routes.rb
resources :movies do
resources :comments, module: :movies
resources :parts do
resources :comments, module: :parts
end
end
app/views/movies/show.html.erb
<%= render partial: "comments/comments", locals: {commentable: #movie} %>
<%= render partial: "comments/form", locals: {commentable: #movie} %>
app/views/comments/_comments.html.erb
<h1>Comments</h1>
<% commentable.comments.each do |comment| %>
<div class="well">
<%= comment.summary %> by <i><%= comment.user.email %></i><br><br>
</div>
<% end %>
app/views/comments/_form.html.erb
<%= form_for [commentable, Comment.new] do |form| %>
<% if commentable.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(commentable.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% commentable.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= form.text_area :summary, class: "form-control", placeholder: "Add a comment" %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
Everything above with 'movies' is working well. The problem is with 'parts'.
app/views/parts/show.html.erb
<%= render partial: "comments/comments", locals: {commentable: #part} %>
<%= render partial: "comments/form", locals: {commentable: #part} %>
Error with 'parts'
NoMethodError in Parts#show
undefined method `part_comments_path' for #ActionView::Base:0x0000000003d3b0
Highlighted line of error:
<%= form_for [commentable, Comment.new] do |form| %>
I think I have to pass the movie object with the part object into 'commentable' -- since it is nested -- but don't know how to do it with this set up. Any suggestions are greatly appreciated.
I believe route in the partial meant replacing any references to part_comments_path with movie_part_comments_path.
I'm trying to do something that I imagine to be very basic, but I'm very new to Rails and am not sure what sure what I'm doing wrong. I've gone through several tutorials and searched for an answer and can't find what the issue is. Would appreciate any help!
I've got Models set up so that Clients have many Projects which have many Milestones:
class Client < ActiveRecord::Base
has_many :projects, :dependent => :destroy
end
class Project < ActiveRecord::Base
belongs_to :client
has_many :milestones, :dependent => :destroy
end
class Milestone < ActiveRecord::Base
belongs_to :project
end
Routes are set up as follows:
resources :clients
resources :milestones
resources :projects do
resources :milestones
end
In projects/show.html.erb, I want to display each milestone associated with a project and also provide a form that adds new milestones on that same page. When I submit the form, it adds a new milestone (a new LI within UL.card-list), but none of the values show up. Here is the code for projects/show.html.erb:
<h2><%= #project.name %> Milestones</h2>
<ul class="card-list">
<% #project.milestones.each do |m| %>
<li>
<div class="card-header">
<%= m.date %>
</div>
<div class="card-body">
<h3 class="name"><%= m.name %></h3>
<p class="description"><%= m.description %></p>
</div>
</li>
<% end %>
<li>
<div class="card-header">
New Milestone
</div>
<div class="card-body">
<%= form_for [#project,Milestone.new] do |f| %>
<%= f.hidden_field(:project_id, value: #project.id) %>
<div class="field">
<%= f.label :milestone %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :date %>
<%= f.date_field :date %>
</div>
<div class="actions">
<%= f.submit "Add Milestone" %>
</div>
<% end %>
</div>
</li>
</ul>
Here are the parameters that are coming through the form:
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"3D12GTH+IhwMMQDKsj2l+KXe7OBxmub3eejb3pbpWao=",
"milestone"=>{
"project_id"=>"1",
"name"=>"Test Milestone",
"description"=>"test descrip",
"date"=>"2015-06-26"
},
"commit"=>"Add Milestone",
"project_id"=>"1"
}
Milestones controller:
def create
#project = Project.find(params[:project_id])
#milestone = #project.milestones.create!(params[milestone_params])
redirect_to #project
end
private
def milestone_params
params.require(:milestone).permit(:name, :description, :completed, :date, :project_id)
end
Please let me know if there's any other info I can provide that would help. Thanks!
Since you need to support both (POST /milestones and POST /projects/:project_id/milestones) the project_id to the form:
<%= form_for [#project,Milestone.new] do |f| %>
...
<%= f.hidden_field(:project_id, value: #project_id) %>
...
<%- end -%>
Or if your resource is always nested than project_id available in the params in your controller so you can just pass it:
class MilestonesContoller < ApplicationController
def create
#milestone = Milestone.new(milestone_params)
# this part was originally omitted for brevity.
if #milestone.save
redirect_to #milestone.project
else
render :new
end
end
# don't trust params from the scary interwebs
def milestone_params
params.require(:milestone)
.permit(:project_id, :name, :description, :date)
end
end
NOTE that you actually need to integrate this code with the other actions in your controller. It is just a minimal example to show the relevant concepts. Not something which is meant as a complete copy-paste-done solution.
You can also reduce your routes file down to:
resources :clients
resources :milestones
resources :projects do
resources :milestones
end
Use the options for resources if you need to customize the routes.
I am creating a form for submitting student details in the first step and in the second step parent (guardian) details should be submitted.
I have created a controller for student and another for the guardian, after filling the details , i need when pressing on submit button at first step , the step two should appear which is parent/guardian details but i am having a problem in achieving this. and my files are:
students_controller.rb
class StudentsController < ApplicationController
def index
#student = Student.all
end
def show
#student = Student.find(params[:id])
end
def new
#student = Student.new
end
def create
#student = Student.new(params[:student])
if #student.save
flash[:success] = ' Student Record Saved Successfully. Please fill the Parent Details.'
render 'guardians/new'
else
flash.now[:error] = 'An error occurred please try again!'
render 'new'
end
end
def edit
end
end
student.rb
class Student < ActiveRecord::Base
attr_accessible :address_line1, :address_line2, :admission_date, :admission_no, :birth_place, :blood_group, :city,
:class_roll_no, :date_of_birth, :email, :first_name, :gender, :language, :last_name, :middle_name,
:phone1, :phone2, :post_code, :religion, :country_id, :nationality_id
belongs_to :user
belongs_to :country
belongs_to :school
belongs_to :batch
belongs_to :nationality , class_name: 'Country'
has_many :guardians , foreign_key: 'ward_id'
has_many :student_previous_subject_marks
has_one :student_previous_data
end
guardians_controller.rb
class GuardiansController < ApplicationController
def index
end
def show
end
def new
#guardian = Guardian.new
end
def edit
end
end
guardian.rb
class Guardian < ActiveRecord::Base
attr_accessible :city, :dob, :education, :email, :first_name, :income, :last_name, :mobile_phone, :occupation,
:office_address_line1, :office_address_line2, :office_phone1, :office_phone2, :relation
belongs_to :user
belongs_to :country
belongs_to :school
belongs_to :ward , class_name: 'Student'
end
routes.rb
Triton::Application.routes.draw do
get "guardians/index"
get "guardians/show"
get "guardians/edit"
get "students/index"
get "students/show"
get "students/edit"
resources :articles do
resources :comments
end
resources :users
resources :guardians
resources :students
resources :sessions
get '/user/dashboard', to: 'static_pages#home'
get '/student/admission1' , to: 'students#new'
get '/student/admission2' , to: 'guardians#new'
root to: 'sessions#new'
end
students/new.html.erb
<h1>Admission</h1>
<h4>Step 1 - Student details</h4>
<div>
<div class="span6 offset2">
<%= form_for(#student) do |f| %>
<% if #student.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#student.errors.count, 'error') %>
</div>
<ul>
<% #student.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<table border="0" style="width: 65%" class='hero-unit'>
<tr>
<th><div class="field"><%= f.label :admission_no %></div></th>
<th><div class="field"><%= f.text_field :admission_no %></div></th>
</tr>
<tr>
<th><div class="field"><%= f.label :admission_date %></div></th>
<th><div class="field"><%= f.text_field :admission_date , :class => 'datepicker'%></div></th>
</tr></table>
<h4>Student - Personal Details</h4>
<table border="0" style="width: 65%" class='hero-unit'>
<tr>
<th><div class="field"><%= f.label :first_name %></div></th>
<th><div class="field"><%= f.text_field :first_name %></div></th>
</tr>
<tr>
guardians/new.html.erb
<h1>Admission</h1>
<h4>Step 2 - Parent details</h4>
<div class="row-fluid">
<div class="span4 offset1 hero-unit">
<%= form_for #guardian do |f| %>
<% if #guardian.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(#guardian.errors.count, 'error') %>
</div>
<ul>
<% #guardian.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<div class="field">
<%= f.label 'Student Admission number' %>
<%= f.text_field :ward_id , disabled: true %>
</div>
<h4>Parent - Personal Details</h4>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
//not the whole file, just copied what is needed to be seen
the error i am facing
NoMethodError in Students#create
undefined method `model_name' for NilClass:Class
Extracted source (around line #45):
42:
43: <div class="row-fluid">
44: <div class="span4 offset1 hero-unit">
45: <%= form_for #guardian do |f| %>
46: <% if #guardian.errors.any? %>
47: <div id="error_explanation">
48: <div class="alert alert-error">
I hope you can get my point to solve my problem and thanks !!
This could be a few things:
Change the line from:
<%= form_for #guardian do |f| %>
to:
<%= form_for :guardian => {:action => :create} do |f| %>
If this doesn't work. delete the line {:action => :create}
other things that might be the problem.
You have two controllers and haven't said which is the relevant one.
Neither of your controllers is setting the plural #guardian referenced in your view
You should
redirect_to new_guardian_url
instead of
render 'guardians/new'
inside your students_controller.rb
Trying to do a many to many relations ship.
I have two models, Teams and Matches and i'm doing a many-to-many relations ship but getting this error when trying to save a nested model.
'Couldn't find Team with ID=2 for Match with ID='
I know that my model is new so it doesn't have an id yet, but i'm using the Match.new(params[:match] method which should work.
Team:
class Team < ActiveRecord::Base
attr_accessible :description, :name, :status
attr_protected :id
has_many :matchships
has_many :matches, :through => :matchships
end
Match:
class Match < ActiveRecord::Base
attr_accessible :date, :name
attr_protected :id
has_many :matchships
has_many :teams , :through => :matchships
accepts_nested_attributes_for :teams
end
MatchShips:
class Matchship < ActiveRecord::Base
attr_accessible :match_id, :team_id
belongs_to :match
belongs_to :team
end
Match Controller:
New:
def new
#match = Match.new
#match.teams.build
end
Create:
def create
'failing here' --------> #match = Match.new(params[:match])
#team = Team.find(params[:team_id])
#match.teams << #team
#team.matches << #match
Form:
<%= nested_form_for(#match) do |f| %>
<% if #match.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#match.errors.count, "error") %> prohibited this match from being saved:</h2>
<ul>
<% #match.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :date %><br />
<%= f.date_select :date %>
</div>
<%= f.fields_for :teams, :html => { :class => 'form-vertical' } do |builder| %>
<%= builder.label "Team Name:" %>
<%= builder.autocomplete_field :name, autocomplete_team_name_teams_path, :update_elements => {:id => "##{form_tag_id(builder.object_name, :id)}" },:class => "input-small",:placeholder => "Search" %>
<%= builder.hidden_field :id %>
<% end %>
<%= f.link_to_add raw('<i class="icon-plus-sign"></i>'), :teams, :class => 'btn btn-small btn-primary' %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Controller
I am following railscasts 196 episode and i try exactly what he has, but i am having the following error
ActiveModel::MassAssignmentSecurity::Error in SurveysController#create
Can't mass-assign protected attributes: questions_attributes
Rails.root: /home/jean/rail/surveysays
Here my code so far
Survey Form
<%= form_for(#survey) do |f| %>
<% if #survey.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#survey.errors.count, "error") %> prohibited this survey from being saved:</h2>
<ul>
<% #survey.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<%= f.fields_for :questions do |bf|%>
<%= bf.label :content, "Question" %><br />
<%= bf.text_area :content, :rows=> 3 %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Survey Relationship
class Survey < ActiveRecord::Base
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions
attr_accessible :name
end
Question Relationship
class Question < ActiveRecord::Base
belongs_to :survey
attr_accessible :content, :survey_id
end
New Controller
def new
#survey = Survey.new
3.times {#survey.questions.build }
respond_to do |format|
format.html # new.html.erb
format.json { render json: #survey }
end
end
change your class to this
class Survey < ActiveRecord::Base
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions
attr_accessible :name, :questions_attributes
end
look for topic "Using with attr_accessible" here for more information