Hey i´ve got another problem ;)
When i try to create a new Book in my app it always says
undefined method "model_name" for NilClass:Class
I found out that it must be an uninitialized param in the Form_for function... Here my code:
NoMethodError in Books#new
Showing /app/views/books/_form.html.erb where line #1 raised:
undefined method `model_name' for NilClass:Class
Extracted source (around line #1):
1: <%= form_for(#book) do |f| %>
2: <% if #book.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#book.errors.count, "error") %> prohibited this book from being saved:</h2>
Controller:
#GET /books/new
#GET /books/new.json
def new
#users = User.find(:all)
#book = Book.new
1.times{ #book.chapters.build }
#book.users = [current_user]
respond_to do |format|
format.html #new.html.erb
format.json { render json: #book }
end
end
I don´t know why it should be uninitialized, it worked properly before I changed some relations between Books and Users but I there shoudn´t be the failure or?
EDIT:
app/views/books/new.html.erb :
<h1>New book</h1>
<%= render 'form' %>
<%= link_to 'Back', books_path %>
And the Model :
class Book < ActiveRecord::Base
attr_accessible :abstract, :status, :titel, :user_tokens, user_ids, :chapters_attributes
has_and_belongs_to_many :users
attr_reader :user_tokens
has_many :chapters, :dependent => :destroy, :autosave => true, :order => 'slot'
validates :title, :presence => true
accepts_nested_attributes_for :chapters, :allow_destroy => true
after_initialize :init
def init
self.status = false if self.status?
end
def user_tokens=(ids)
self.user_ids = ids.split(",")
end
end
end
Your partial will not know the instance variables you set up in the controller. You will have to pass them as locals when you render the partial
render :partial => "form", :locals => {:book => #book}
And in your partial, use book instead of #book
<%= form_for(book) do |f| %>
<% if book.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(book.errors.count, "error") %> prohibited this book from being saved:</h2>
Related
Okay, so I am currently working on a commenting system where posts belong to classrooms and posts have comments. So classrooms have comments through posts.
Here are the models
class Classroom < ActiveRecord::Base
has_many :posts
has_many :comments, through: :posts
...
end
class Comment < ActiveRecord::Base
belongs_to :post
...
end
class Post < ActiveRecord::Base
belongs_to :classroom
has_many :comments
...
end
I'm trying to save post_ids but it won't let me with a simple hidden field so I tried it with a value and it still doesn't work. it says that post_id is an undefined method.
Here is my classroom controller's show method because it is where the new comment form is being rendered.
def show
#classroom = Classroom.find(params[:id])
#posts = #classroom.posts
#comments = #classroom.comments
#comment = Comment.new
end
Here is the new comment form.
<%= simple_form_for(#comment) do |f| %>
<%= f.error_notification %>
<%= f.text_area :content %>
<%= f.hidden_field :post_id, :value => #classroom.post_id %>
<div class="form-actions">
<br>
<%= f.button :submit %>
</div>
<% end %>
Error Message
NoMethodError in Classrooms#show
undefined method `post_id' for Classroom:0x007f52aa646b18
How do I save the post_id?
Thanks!
NoMethodError in Classrooms#show undefined method `post_id' for
Classroom:0x007f52aa646b18
<%= f.hidden_field :post_id, :value => #classroom.post_id %>
The error is obvious as you are doing #classroom.post_id as Classroom don't have a field called post_id
Define a #post with the help of #classroom
def show
#classroom = Classroom.find(params[:id])
#post = Post.where(classroom_id: #classroom.id).first
#posts = #classroom.posts
#comments = #classroom.comments
#comment = Comment.new
end
and use that in the hidden_field
<%= f.hidden_field :post_id, :value => #post.id %>
I'm trying to extend the Rails Tutorial Sample App to include replies.
I created a Recipient model that contains a user_id to designate the person to whom the reply is addressed and a micropost_id.
I added the following to my User model.
class User < ActiveRecord::Base
...
has_many :replies, foreign_key: "user_id", class_name: "Recipient", dependent: :destroy
has_many :received_replies, through: :replies, source: :micropost
...
def feed
Micropost.from_followed_by_and_replying_to(self)
end
...
end
And this to my Micropost model:
class Micropost < ActiveRecord::Base
belongs_to :user
...
has_many :recipients, dependent: :destroy
has_many :replied_users, through: :recipients, :source => "user"
...
def self.from_followed_by_and_replying_to(user)
followed_ids = "SELECT followed_id FROM relationships
WHERE followed_id = :user_id"
replier_ids = "SELECT micropost_id FROM recipients
WHERE user_id = :user_id"
where("user_id in (#{followed_ids})
OR id in (#{replier_ids}) OR user_id = :user_id",
user_id: user.id)
end
...
end
The StaticPages#home action loads the feed:
class StaticPagesController < ApplicationController
def home
if signed_in?
#micropost = current_user.microposts.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
...
end
Then when signed in and visiting the home page, I get NoMethodError in StaticPages#Home for the shared feed_item partial (app/views/shared/_feed_item.html.erb) at this line:
<%= link_to gravatar_for(feed_item.user), feed_item.user %>
It's undefined method 'email' for nil:NilClass (presumably from user.email which the gravatar_for helper method uses.
When I call Micropost.from_followed_by_and_replying_to([some user]) in the rails console, it has no trouble returning both the microposts from followed users as well as replies, so I don't think my db querying is incorrect here. Any help is appreciated, I'm really stumped.
edit: (removed some HTML from these)
app/views/static_pages/home.html.erb:
<% if signed_in? %>
...
<%= render 'shared/user_info' %>
<%= render 'shared/stats' %>
<%= render 'shared/micropost_form' %>
<%= render 'shared/feed' %>
...
<% else %>
...
<% end %>
app/views/shared/_feed.html.erb:
<% if #feed_items.any? %>
<%= render partial: 'shared/feed_item', collection: #feed_items %>
<%= will_paginate #feed_items %>
<% end %>
app/views/shared/_feed_items.html.erb:
<li id="<%= feed_item.id %>">
<%= link_to gravatar_for(feed_item.user), feed_item.user %>
<%= link_to feed_item.user.name, feed_item.user %>
...
</li>
If gravatar_for calls email on the user you pass to it, then the error message is telling you that feed_item.user is nil.
Try putting <% raise feed_item.user %> the line before the link_to, and see if it is indeed nil. Also, a stack trace of the error is one of the most useful things you can put in a SO question.
i'm building a relations Company :has_many Notes.
i want to be able to add some new notes to a just created company in the Comany#show resource. so in the company scaffold's show.html.erb
i have follwed step by step the cocoon demostration app and from the github mardown, but the examples shows only the method to add nested attribute into _form.html.erb partial. I don't know if there is some particular things to do differently, but when i try to run the Company#show action it retrieves this error:
undefined method `new_record?' for nil:NilClass
this is my code:
show.html.erb:
...
<%= simple_form_for :notes, :html => { :class => 'form-horizontal' } do |note| %>
<%= render 'note_fields', :f => note %>
<% end %>
<%= link_to_add_association 'Aggiungi Nota', f, :notes, :render_options => {:wrapper => 'inline' } %>
...
_note_fields.html.erb:
...
<div class="nested-fields">
<%= f.input :body %>
<%= link_to_remove_association "Elimina Nota", f %>
</div>
...
Company.rb:
...
has_many :notes
accepts_nested_attributes_for :notes, :reject_if => :all_blank, :allow_destroy => true
...
Note.rb
class Note < ActiveRecord::Base
attr_accessible :body, :company_id
belongs_to :company
end
company_controller.rb
def show
#company = Company.includes(:category, :clients, :notes).find(params[:id])
#mapCompany = Company.find(params[:id]).to_gmaps4rails
respond_to do |format|
format.html # show.html.erb
format.json { render json: #company }
end
end
thanks!
Dave
In the following code, the f variable was never defined.
<%= link_to_add_association 'Aggiungi Nota', f, :notes, :render_options => {:wrapper => 'inline' } %>
Try using company instead of f.
Ok so i am tring to list my genres in a f.select form and I am getting an error. I have look everywhere and i am just not understanding what i am doing differently. when I enter rails c and type g = Genre.all it lists all genres then g.map out puts => #<Enumerator: ...>
Error:
undefined method `map' for nil:NilClass
View Page:
<%= f.fields_for :genres do |g| %>
<div class="field">
<%= g.label :genre %>
<%= g.select :genres, #genres.map {|g| g.name} %>
</div>
<% end %>
Controller:
def create
#song = Song.new(params[:song])
#genres = Genre.all
if #song.save
redirect_to player_path
else
render :new
end
end
You need to assign #genres variable in new action too:
def new
#genres = Genre.all
end
I am trying to allow a user to enter a project into a database. One of the fields allows them to enter multiple technologies for that project.
Here is my project controller, new and create action.
def new
#project = Project.new
#all_technols = Technol.all
#project_technol = #project.projecttechnols.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #project }
end
end
def create
#project = Project.new(params[:project])
params[:technols][:id].each do |technol|
if !technol.empty?
#project.projecttechnols.build(:technol_id => technol)
end
end
end
Here is my new project view for the multi select technology dropdown.
<%= fields_for(#project_technol) do |ab| %>
<div class="tech">
<%= ab.label "All Tech" %><br/>
<%= collection_select(:technols, :id, #all_technols, :id, :tech, {}, {:multiple => true} ) %>
</div>
<% end %>
project.rb
class Project < ActiveRecord::Base
attr_accessible :tech
has_many :projecttechnols
has_many :technols, :through => :projecttechnols
end
technol.rb
class Technol < ActiveRecord::Base
attr_accessible :tech
has_many :projecttechnols
has_many :projects, :through => :projecttechnols
end
projecttechnol.rb
class Projecttechnol < ActiveRecord::Base
attr_accessible :project_id, :technol_id
belongs_to :technol
belongs_to :project
end
At the moment, I have a page where the user can enter a new technology. But I want to move this option to the create new project page, where they can either select existing technologies, or enter a new one, or do both, and they would save with that project.
When I try to save a new project however, I am getting this error.
Showing /home/james/Desktop/webapp/app/views/projects/new.html.erb where line #233 raised:
undefined method `model_name' for NilClass:Class
Extracted source (around line #233):
233: <%= fields_for(#project_technol) do |ab| %>
234:
235: <div class="tech">
236: <%= ab.label "All Tech" %><br/>
I am new to rails and still learning so please remember when answering. Thanks in advance.
EDIT
after changing
#project.projecttechnols.build(:technol_id => technol)
to
#project_technol = #project.projecttechnols.build(:technol_id => technol)
I now get this error:
NoMethodError in Projects#create
undefined method `map' for nil:NilClass
Extracted source (around line #240):
237: <div class="tech">
238: <%= ab.label "All Tech" %><br/>
239:
240: <%= collection_select(:technols, :id, #all_technols, :id, :tech, {}, {:multiple => true} ) %>
241: </div>
242: <% end %>
EDIT 2
#all_technols = Technol.all in the create action
I now get this error.
NoMethodError in Projects#show
Showing /home/james/Desktop/webapp/app/views/projects/show.html.erb where line #181 raised:
undefined method `technol' for #<Project:0xb36823c>
Extracted source (around line #181):
178: <h3>Related books</h3>
179:
180: <ul>
181: <% #project.technol.each do |technol| %>
182: <li><%= technol.tech %> <%= link_to "Details", technol_path(technol) %></li>
183: <% end %>
184: </ul>
Your create action is rendering the new view again. However, #project_technol is not defined within the create action. The fields_for method calls model_name method on the argument passed in (#project_technol), but since #project_technol = nil, it's throwing that error. To fix this, within your create action, change
#project.projecttechnols.build(:technol_id => technol)
to
#project_technol = #project.projecttechnols.build(:technol_id => technol)