I saw similar examples here. But it just doesn't work for me.
I want to create/submit an activity for post. There are several days under a post. And an activity is under a specific date. See models below.
Models:
class Post < ActiveRecord::Base
has_many :dayinposts
has_many :activitys, :through => :dayinposts
end
class Dayinpost < ActiveRecord::Base
belongs_to :post
has_many :activitys
end
class Activity < ActiveRecord::Base
belongs_to :dayinpost
end
Routes:
resources :posts do
resources :dayinposts do
resources :activitys
end
end
rake routes
post_dayinpost_activitys GET /posts/:post_id/dayinposts/:dayinpost_id/activitys(.:format) activitys#index
POST /posts/:post_id/dayinposts/:dayinpost_id/activitys(.:format) activitys#create
show.html.erb
<% #post.dayinposts.each do |dayinpost| %>
<% dayinpost.activitys.each do |activity| %>
<p>
<b>Action:</b>
<%= activity.action %>
</p>
<% end %>
<%= form_for([#post, dayinpost, dayinpost.activitys.build]) do |f| %>
<div class="field">
<%= f.label :action %><br />
<%= f.text_field :action %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<% end %>
error
undefined method `post_dayinpost_activities_path' for #<#<Class:0x40cb6d8>:0x40c9890>
But I have saw it in the rake routes...
thanks in advance!
The correct pluralization for "activity" is "activities".
In your config/routes.rb you have "activitys", which is wrong.
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 trying to make an app in Rails 4.
I have a projects, project questions and a project answers model.
my models
class Project
has_many :project_questions, dependent: :destroy#, through: :projects
accepts_nested_attributes_for :project_questions
end
class ProjectQuestions
belongs_to :project#, counter_cache: true
has_many :project_answers, dependent: :destroy
belongs_to :user
accepts_nested_attributes_for :project_answers
end
class ProjectAnswer
belongs_to :project_question#, counter_cache: true
belongs_to :user
end
routes.rb
resources :projects do
# patch '/toggle-draft', to 'projects#toggle_draft', as: 'toggle_draft'
resources :project_questions do
resources :project_answers
end
end
In my projects_controller, I have permitted params for project questions and answers as follows:
project_question_attributes: [:title, :content, :user_id, :project_id,
project_answer_attributes: [:answer, :project_question_id]],
These params are also permitted in the Project questions and project answers controllers.
In my projects view, I want to render a partial that I have made in my project_questions view folder.
projects/show
<%= link_to 'Ask a question', new_project_question_path %> <% end %>
<%= render 'project_questions/pqps' %>
In my project_questions partial which is called _pqps, I have;
<div class="containerfluid">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<% f.simple_fields_for :project_questions, #project.project_questions.build do |f| %>
<div class="categorytitle">
<%= f.title %>
</div>
<div class="generaltext">
<%= f.content %>
</div>
<%= render 'project_answers/show' %>
<span class="editproject"> <% if current_user.id == #project.creator_id %>
<%= link_to 'Answer this question', new_project_answer_path %>
<% end %>
</span>
<% end %>
</div>
</div>
</div>
When I try this, I get an error that says:
undefined local variable or method `f' for #<#:0x0000010a11ce60>
I thought I was defining f at the beginning of the opening line of the _pqps form.
I'm really struggling to get a grip with coding. Can anyone see what I've done wrong?
You use f.simple_fields_for in pqps, but f is not defined anywhere.
You have to define it using simple_form_for somewhere. I don't know exactly where – it depends on your own needs, but if, say, the whole form is inside _pqps:
<div class="containerfluid">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<%= simple_form_for #project do |f| %>
<% f.simple_fields_for :project_questions, #project.project_questions.build do |f| %>
# ...
<% end %>
<% end %>
</div>
</div>
</div>
If form "starts" outside "_pqps" partial, then you have to pass f as a local parameter:
<%= render 'project_questions/pqps', f: f %>
projects_controller
def show
#project_questions = #project.project_questions.build
end
View
<%= simple_form_for #project_questions do |f| %>
<%= f.input :title%>
<%= f.input :content %>
<%= f.button :submit %>
<% end %>
#reckoner has_many #shift_requirements and in routes,
resources :reckoners do
resources :shift_requirements
end
In a view under reckoner_controller.rb I have
<%= link_to 'create a shift', [:new, #reckoner, :shift_requirement]%>
... which fires the correct view containing a form helper. Then it throws the error -
undefined method `shift_requirements_path' for #<#<Class:0x007f908e00a458>:0x007f908e8a09c8>
How have I gone wrong?
shift_requirement.rb is -
class ShiftRequirement < ActiveRecord::Base
belongs_to :reckoner
end
reckoner.rb is -
class Reckoner < ActiveRecord::Base
has_many :shift_requirements
end
... and the view in the form is now
<%= form_for(#reckoner, #shift_requirement) do |f| %>
...
<%= f.submit %>
I assume your form has:
<%= form_for(#shift_requirement) do |f| %>
<%= f.submit %>
<% end %>
Because of your nested routes you want
<%= form_for([#reckoner, #shift_requirement]) do |f| %>
<%= f.submit %>
<% end %>
I am using a has many through association so that an article can be 'saved' to many sections and that relation is called a location. In the locations table there is also a 'default' column (boolean), this allows the user to indicate which section is the default one.
Here are the models:
class Article < ActiveRecord::Base
has_many :locations
has_many :sections, :through => :locations
def default_location
self.sections.where('locations.default = 1').first
end
end
class Location < ActiveRecord::Base
belongs_to :article
belongs_to :section
end
class Section < ActiveRecord::Base
has_many :locations
has_many :articles, :through => :locations
end
So in my view:
<%= form_for(#article) do |f| %>
...
<p class="field">
<h3>Locations</h3>
<ul>
<% #sections.each do |section| %>
<li><%= radio_button_tag ???, section.id, :checked => #article.default_location == section %> <%= check_box_tag 'article[section_ids][]', section.id, #article.section_ids.include?(section.id), :id => dom_id(section) %><%= label_tag dom_id(section), section.name %></li>
<% end %>
</ul>
</p>
...
<% end %>
So far I can save and update the locations fine but I'm not sure how to assign the default field to each location saved. I have added a radio button for each section so the user can select the default but I'm not sure how to tie it all together.
Any ideas will be really appreciated! Thanks.
Not sure why you need both a radio button and check box. Try adding a hidden_field_tag along with a check_box_tag:
<p class="field">
<h3>Locations</h3>
<%= hidden_field_tag "article[section_ids][]", "" %>
<ul>
<% #sections.each do |section| %>
<li>
<%= check_box_tag :section_ids, section.id, #article.section_ids.include?(section.id), :id => dom_id(section), :name => 'article[section_ids][]' %>
<%= label_tag dom_id(section), section.name %>
</li>
<% end %>
</ul>
</p>