I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is
undefined method `post_comments_path' for #<#<Class:0x2aef820>:0x2bd7df8>
Extracted source (around line #25):
<h2>Add a comment:</h2>
<%= form_for([#post, #post.comments.build]) do |f| %>...here it is line number 25
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
I have two model
post.rb
class Post < ActiveRecord::Base
has_many :comments
validates :title, presence: true,
length: { minimum: 5 }
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
end
I have two controllers
posts_controller.rb
class PostsController < ApplicationController
def new
#post=Post.new
end
def show
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path
end
def create
#post = Post.new(post_params)
# it will also works #post=Post.new(params[:post].permit(:title,:text))
if #post.save
redirect_to #post
# or this command also works redirect_to action: :show, id: #post.id
else
render 'new'
end
end
def index
#posts = Post.all
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
comments_controller.rb
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(params[:comment].permit(:commenter, :body))
redirect_to post_path(#post)
end
end
my routes.rb file is
Blog::Application.routes.draw do
resources :posts do
resources :comments
end
I have two migration files
create_posts.rb
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :text
t.timestamps
end
end
end
create_comments.rb
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :post
#above line sets foreign key column for the association between the two models.
t.timestamps
end
#and bellow add_index line sets up an index for this association column.
add_index :comments, :post_id
end
end
my show.html.erb file is
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<p>
<strong>Text:</strong>
<%= #post.text %>
</p>
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([#post, #post.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit Post', edit_post_path(#post) %> |
<%= link_to 'Back to Posts', posts_path %>
I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is
I have a feeling you missed the part about nested resources. As in:
resources :posts do
resources :comments
end
This means the routes generated by resources :comments are nested within your posts, which results in URLs like this:
/posts/1/comments
Related
I am new to the rails community. I am working on an application where users can have username with a nested attribute of first and last name. The other text field associated with the User model works fine.
Any help would be much appreciated.
Attached are the app models, controllers, migration files, db schema, and views.
models
class User < ActiveRecord::Base
has_one :username, dependent: :destroy
accepts_nested_attributes_for :username, allow_destroy: true
end
class Username < ActiveRecord::Base
belongs_to :user
end
Migrations
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :about_me
t.string :nationality
t.string :sexe
t.timestamps null: false
end
end
end
class CreateUsernames < ActiveRecord::Migration
def change
create_table :usernames do |t|
add_column :username, :first_name, :string
add_column :username, :last_name, :string
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
controller
class UsersController < ApplicationController
def index
#all_users = User.all
#new_user = User.new
#username = Username.new
end
def new
#new_user = User.new
end
def create
User.create(user_params)
end
private
def user_params
params.require(:user).permit(:email, :about_me, username_attributes:
[:last_name, :first_name])
end
end
Views
<h1>Users#index</h1>
<p>Find me in app/views/users/index.html.erb</p>
<%= form_for #new_user do |f| %>
<%= f.fields_for #new_user do |user| %>
<div class="field">
<%= user.label :email%>
<%= user.text_field :email %>
<%= user.label :about_me %>
<%= user.text_field :about_me %>
</div>
<% end %>
<%= f.fields_for :username do |name| %>
<div class="field">
<%= name.label :first_name %>
<%= name.text_field :first_name %>
</div>
<% end %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Try this
controller
def new
#new_user = User.new
#new_user.usernames.build
end
view
<%= form_for #new_user do |f| %>
# ...
<%= f.fields_for :usernames do |name| %>
<div class="field">
<%= name.label :first_name %>
<%= name.text_field :first_name %>
</div>
<% end %>
# ...
<% end %>
helper
def name_format(user_mst)
name = user_mst.first_name.capitalize
name += (" #{user_mst.last_name.capitalize}")
return name
end
to display on view
I would like with Rails4 to assign the current_user.email to a comment.
This comment is assign to a book.
[Page book][1] [1]: http://i.stack.imgur.com/2mEoG.png
I succeed to assign the current_user.email to a comment
but when i try to change the current_user with an other account, all the email of the comments change also. And i don't want that!
How can i resolve the problem?
Here some files of my app:
CommentsController:
class CommentsController < ApplicationController
def create
#book = Book.find(params[:book_id])
#comment = #book.comments.new(comment_params)
if #comment.save
redirect_to #comment.book, notice: I18n.t('books.comment')
else
render text: 'Error!'
end
end
private
def comment_params
params.require(:comment).permit(:message)
end
end
view:
<% if comment.message != nil %>
<li><strong><%= current_user.email %></strong></li>
<p><%= comment.message %></p>
<% end %>
form_for:
<%= form_for [#book, #comment] do |f| %>
<%= f.hidden_field :book_id %>
<%= f.text_area :message, :placeholder => "Message" %>
<br />
<%= f.submit %>
<% end %>
Table Comments:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :message
t.string :username
t.integer :book_id
t.integer :reader_id
t.integer :user_id
t.timestamps
end
end
end
Table Readers:
class CreateReaders < ActiveRecord::Migration
def change
create_table :readers do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
Table Books:
class CreateBooks < ActiveRecord::Migration
def change
create_table :books do |t|
t.string :title
t.string :author
t.string :synopsis
t.timestamps
end
end
end
Well, if you want have assigned current user to comment you can place a hidden field to save users id (make sure you have configured associations in models):
form_for:
<%= form_for [#book, #comment] do |f| %>
...
<%= f.hidden_field :user_id, value: current_user.id %>
...
<% end %>
Update comment_params in controller:
private
def comment_params
params.require(:comment).permit(:message, :user_id)
end
and then, in view:
<% if comment.message != nil %>
<li>
<strong>
<%= comment.user.email %>
</strong>
</li>
<p><%= comment.message %></p>
<% end %>
That's it. If you need use reader model instead of user - you can do it in the same way..
I have 2 forms in page which are as below and even i include the error printing sections those are not getting printed
<code>
<div id="tabs-2">
<% if #user.personal %>
<h2>Personal Details</h2>
<div class="image"><%= image_tag (#user.personal.avatar_url(:thumb))if #user.personal.avatar? %></div>
<b>First Name</b>: <%= #user.personal.first_name %><br>
<b>Middle Name</b>: <%= #user.personal.middle_name %><br>
<b>Last Name</b>: <%= #user.personal.last_name %><br>
<b>Date of Birth</b> <%= #user.personal.date_of_birth %><br>
<b>Gender</b>: <%= #user.personal.gender %><br>
<b>Category</b> <%= Category.find(#user.personal.category_id).category %><br>
<b>Blood Group</b>: <%= #user.personal.blood_group %><br>
<b>Fathers_name</b>: <%= #user.personal.fathers_name %><br>
<b>Mothers_name</b>: <%= #user.personal.mothers_name %><br>
<% else %>
<%= form_for([#user, Personal.new]) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this candidate from being saved:</h2>
<ul>
<% #user.personal.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :first_name %><br/>
<%= f.text_field :first_name %>
</p>
<p>
<%= f.label :middle_name %><br/>
<%= f.text_field :middle_name %>
</p>
<p>
<%= f.label :last_name %><br/>
<%= f.text_field :last_name %>
</p>
<p>
<%= f.label :date_of_birth, "Date of Birth" %><br/>
<%= f.date_select :date_of_birth, start_year: 1985, end_year: 1999 %>
</p>
<p>
<%= f.label :gender %><br/>
<%= f.select :gender, options_for_select(%w[M F O]) %>
</p>
<p>
<%= f.label :blood_group %><br/>
<%= f.select :blood_group, options_for_select(%w[AB A+ B+ O ]) %>
</p>
<p>
<%= f.label :fathers_name %><br/>
<%= f.text_field :fathers_name %>
</p>
<p>
<%= f.label :mothers_name %><br/>
<%= f.text_field :mothers_name %>
</p>
<p>
<%= f.label :category_id %></br>
<%= select("personal", "category_id", Category.all.collect {|c| [c.category, c.id]}) %>
</p>
<p>
<%= f.label :avatar %>
<%= f.file_field :avatar %>
</p>
<p><%= f.submit "Submit", data: {confirm: "Are you sure information once submitted cant be modified ?"} %></p>
<% end %>
<% end %>
</code>
This is the first form this is getting in
app/views/user_dashboard/home.html.erb
I cant figure this out why the errors are not getting printed on failing the validations
present in personal.rb
class Personal < ActiveRecord::Base
# every personal information belongs to a particular user
belongs_to :user
# carrierwave uploader
mount_uploader :avatar, AvatarUploader
# validations
validates :first_name, presence: true, length: { maximum: 24}
validates :middle_name, length: { maximum: 24}
validates :last_name, presence: true, length: { maximum: 24}
validates :date_of_birth, presence: true
validates :gender, presence: true, length: { maximum: 1}
validates :category_id, presence: true
validates :blood_group, presence: true, length: { maximum: 2}
validates :fathers_name, presence: true, length: { maximum: 24}
validates :mothers_name, presence: true, length: { maximum: 24}
validates :avatar, presence: true
end
here is the personals_controller.rb
class PersonalsController < ApplicationController
before_action :set_personal, only: [:show, :edit, :update, :destroy]
# This helps to create personals
def create
#user = current_user
#personal = #user.create_personal(personal_params)
redirect_to home_path
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def personal_params
params.require(:personal).permit(:user_id, :category_id, :avatar, :date_of_birth, :gender, :blood_group, :fathers_name, :mothers_name, :address_present, :first_name, :last_name, :middle_name)
end
end
and here are some logs
Started POST "/users/36/personals" for 127.0.0.1 at 2014-07-11 23:57:20 +0530
Started POST "/users/36/personals" for 127.0.0.1 at 2014-07-11 23:57:20 +0530
Processing by PersonalsController#create as HTML
Processing by PersonalsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"8qku1i/aIlz1aBdypnARzpiKuChWupPCMesjGoNmaTY=", "personal"=>{"first_name"=>"", "middle_name"=>"", "last_name"=>"", "date_of_birth(1i)"=>"1985", "date_of_birth(2i)"=>"7", "date_of_birth(3i)"=>"11", "gender"=>"M", "blood_group"=>"AB", "fathers_name"=>"", "mothers_name"=>"", "category_id"=>"1"}, "commit"=>"Submit", "user_id"=>"36"}
Parameters: {"utf8"=>"✓", "authenticity_token"=>"8qku1i/aIlz1aBdypnARzpiKuChWupPCMesjGoNmaTY=", "personal"=>{"first_name"=>"", "middle_name"=>"", "last_name"=>"", "date_of_birth(1i)"=>"1985", "date_of_birth(2i)"=>"7", "date_of_birth(3i)"=>"11", "gender"=>"M", "blood_group"=>"AB", "fathers_name"=>"", "mothers_name"=>"", "category_id"=>"1"}, "commit"=>"Submit", "user_id"=>"36"}
User Load (0.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 36 ORDER BY `users`.`id` ASC LIMIT 1
User Load (0.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 36 ORDER BY `users`.`id` ASC LIMIT 1
(0.1ms) BEGIN
(0.1ms) BEGIN
(0.1ms) ROLLBACK
(0.1ms) ROLLBACK
Personal Load (0.1ms) SELECT `personals`.* FROM `personals` WHERE `personals`.`user_id` = 36 LIMIT 1
Personal Load (0.1ms) SELECT `personals`.* FROM `personals` WHERE `personals`.`user_id` = 36 LIMIT 1
Redirected to http://localhost:3000/home
Redirected to http://localhost:3000/home
Completed 302 Found in 15ms (ActiveRecord: 0.4ms)
Completed 302 Found in 15ms (ActiveRecord: 0.4ms)
Started GET "/home" for 127.0.0.1 at 2014-07-11 23:57:20 +0530
Started GET "/home" for 127.0.0.1 at 2014-07-11 23:57:20 +0530
Processing by UserDashboardController#home as HTML
Processing by UserDashboardController#home as HTML
routes.rb
# http://www.quora.com/How-can-I-use-nested-routes-with-Devise
devise_for :users, :controllers => {:registrations => "registrations"}, :path => 'accounts'
# users has personal academics and applications hence nested routes
resources :users do
resources :personals
resources :academics
resources :applications
end
# user_dashboard controller
post 'user_dashboard/personal_creator'
# Controlpanel route
get 'controlpanels/controlpanel'
get 'controlpanels/resetranks'
get 'controlpanels/generateranks'
# verify routes
get 'vusers/verify'
# dashboard url shortening
match '/home', to: 'user_dashboard#home', via: 'get'
match '/controlpanel', to: 'controlpanels#controlpanel', via: 'get'
match '/verify', to: 'vusers#verify', via: 'get'
# routes for streams
resources :streams
# routes for categories
resources :categories
# routes for cutoffs
resources :cutoffs
There's a more cleaner way to do this. In your controller method(assuming it's home) you can do:
def home
#user = User.find(params[:id]) #your logic to find user
#personal = #user.build_personal #assuming you have user has_one personal association
end
and then in your form
<%= form_for([#user, #personal]) do |f| %>
<% if #personal.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#personal.errors.count, "error") %> prohibited this candidate from being saved:</h2>
<ul>
<% #personal.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<% end %>
Update:
In your create action(assuming this form takes to create action) you need to have something like this:
def create
#user = User.find(params[:id]) # logic to find user
#personal = #user.build_personal(personal_params)
respond_to do |format|
if #personal.save
format.html { redirect_to #personal }
else
format.html { render :action => "home" }
end
end
end
private
def personal_params
params.require(:personal).permit(:your_attributes)
end
Update:
If your form passes validations create_personal will simply create your record and in your case since it doesn't it will simply go to the step below it which is to redirect to home_path and hence no errors
You can even see it in your logs
User Load (0.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 36 ORDER BY `users`.`id` ASC LIMIT 1
(0.1ms) BEGIN
(0.1ms) BEGIN
(0.1ms) ROLLBACK
(0.1ms) ROLLBACK
Personal Load (0.1ms) SELECT `personals`.* FROM `personals` WHERE `personals`.`user_id` = 36 LIMIT 1
Personal Load (0.1ms) SELECT `personals`.* FROM `personals` WHERE `personals`.`user_id` = 36 LIMIT 1
Redirected to http://localhost:3000/home
class PersonalsController < ApplicationController
def create
#user = current_user
#personal = #user.build_personal(personal_params)
if #personal.save
flash[:notice] = "success"
else
flash[:alert] = #personal.errors.full_messages.each{|e|}
end
redirect_to home_path
end
end
Is this is the answer?
I've searched high and low, and found many posts similiar, but can't seem to debug the following code.
I have a project model, which has many many teams. It has many users through teams. Here are the relevant models.
project.rb
class Project < ActiveRecord::Base
has_many :teams
has_many :users, :through => :teams
accepts_nested_attributes_for :teams
end
team.rb
class Team < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
user.rb
class User < ActiveRecord::Base
has_many :teams
has_many :projects, :through => :teams
end
projects_controller.rb
class ProjectsController < ApplicationController
def index
#projects = Project.all
end
def new
#project = Project.new
end
def create
#project = Project.create(project_params)
redirect_to projects_url
end
def show
#project = Project.find(params[:id])
end
def edit
#project = Project.find(params[:id])
end
def update
#project = Project.find(params[:id])
#project.update(type_params)
redirect_to project_url
end
def destroy
#project = Project.find(params[:id])
#project.destroy
redirect_to projects_url
end
end
private
def project_params
params.require(:project)
project_params = params.require(:project).
permit(:name, :code, :description, :externalId,
{:teams_attributes => [:id, :userId, :projectId]})
end
I have a nested form, that should allow me to create a new project and one team (just typing in the ID), however I get an unpermitted parameters exception ("Unpermitted parameters: team")
Whenever I submit the form. Form code is below.
new.html.erb
<h1>Create New Project</h1>
<%=form_for(#project) do |f| %>
<p>
<%=f.label "Name"%>
<%=f.text_field :name%> <br>
<%=f.label "Code"%>
<%=f.text_field :code%> <br>
<%=f.label "External ID"%>
<%=f.text_field :externalId%> <br>
<%=f.label "Description"%>
<%=f.text_field :description%> <br>
</p>
<ul>
<%= f.fields_for :team do |tf| %>
<li>
<%= tf.label 'User Id' %>
<%= tf.text_field :userId %>
<%= tf.label 'Project Id' %>
<%= tf.text_field :projectId %>
</li>
</ul>
<%end%>
<%=f.submit%>
<%end%>
I've paid special attention to the permitted parameters fields, and think I got them right, but, rails disagrees.
Any help would be appreciated
Your nested form doesn't work with has_many because it is singluar. You want to use f.fields_for :teams do instead (plural). Please try the following changes:
project_controller.rb
def new
#project = Project.new
#project.teams.build
end
[...]
private
[...]
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:name, :code, :externalId, :description, teams_attributes: [ :user_id, :project_id ])
end
new.html.erb
<h1>Create New Project</h1>
<%=form_for(#project) do |f| %>
<p>
<%=f.label "Name"%>
<%=f.text_field :name%> <br>
<%=f.label "Code"%>
<%=f.text_field :code%> <br>
<%=f.label "External ID"%>
<%=f.text_field :externalId%> <br>
<%=f.label "Description"%>
<%=f.text_field :description%> <br>
</p>
<ul>
<%= f.fields_for :teams do |tf| %>
<li>
<%= tf.label 'User Id' %>
<%= tf.text_field :user_id %>
<%= tf.label 'Project Id' %>
<%= tf.text_field :project_id %>
</li>
<%end%>
</ul>
<%=f.submit%>
<%end%>
Change this method like this and try
private
def project_params
params.require(:project)
project_params = params.require(:project).
permit(:name, :code, :description, :externalId,
{:teams_attributes => [:id, :userId, :projectId]})
end
to
private
def project_params
params[:project].permit(:name, :code, :description, :externalId,
{:teams_attributes => [:id, :userId, :projectId]})
end
I'm doing the RoR tutorial on rubyonrails.org and have been doing fine up until adding comments to posts.
When I click through to 'show' a post, I get the following error:
ActionController::UrlGenerationError in Posts#show
No route matches {:action=>"index", :controller=>"comments", :id=>"1", :format=>nil} missing required keys: [:post_id]
I have a show method for posts_controller.rb (see below), and, unless there's a typo on the rails guide (likely, since there are others in other spots), I think there's something going on with my routes.rb.
It says the error occurs around line 25 of /show.html.erb.
Title:
<%= #post.title %>
<p>
<strong>Text:</strong>
<%= #post.text %>
</p>
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([:post, #post.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
<%= link_to 'Edit', edit_post_path(#post) %>
/posts_controller.rb
class PostsController < ApplicationController
def new
#post = Post.new
end
def index
#post = Post.all
end
def show
#post = Post.find(params[:id])
end
def create
#post = Post.new(params[:post].permit(:title, :text))
if #post.save
redirect_to #post
else
render 'new'
end
def edit
#post = Post.find(params[:id])
end
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
routes.rb
Myapp::Application.routes.draw do
resources :posts do
resources :comments
end
root "welcome#index"
end
I think the error has something to do with my routes.rb file, but I can't figure out exactly what. Am I nesting my routes for the comments incorrectly?