I have no idea why it is showing me this problem NO Method in Author.
Showing /home/muba/muba/app/views/author/new.html.erb where line #3 raised:
<%= form_for #author do |f| %>
<div class="form-group">
<%= f.label :first_name %><br/>
<%= f.text_field :first_name, class:'form-control' %><br/>
</div>
<% end %>
Author.rb Controller
class AuthorController < ApplicationController
def new
#page_title= 'Add new Author'
#author = Author.new
end
def create
end
def update
end
def edit
end
def destroy
end
def index
end
def show
end
def author_params
params.require(:author).permit(:first_name, :last_name)
end
end
But Same Thing I did for my Categories page that is working. The code is:
<%= form_for #category do |f| %>
<div class="form-group">
<%= f.label :name %><br/>
<%= f.text_field :name, class:'form-control' %><br/>
</div>
<%=f.submit "Submit", class:'btn btn-primary' %>
<%= link_to "Cancel", categories_path, class:'btn btn-default' %>
<% end %>
Category.rb controller
class CategoriesController < ApplicationController
def new
#page_title= 'Add new Category'
#category= Category.new
end
def create
end
def update
end
def edit
end
def destroy
end
def index
end
def show
end
def category_params
params.require(:category).permit(:name)
end
end
I noticed there is issue in your first line it should be
class AuthorsController < ApplicationController
instead of
class AuthorController < ApplicationController
also make sure your controller's file name is authors_controller.rb
Ruby on Rails follow linguistic convention. Check Ruby and Rails Naming Conventions
In your view :
<%= form_for #author do |f| %>
<div class="form-group">
<%= f.label :first_name %><br/>
<%= f.text_field :first_name, class:'form-control' %><br/>
</div>
<% end %>
here , make sure the first_name is present as a column name in your Author model in the table in the database . It will check the exact name in the table which will raise an error if the name doesn't match .
I hope this helps.
Related
I am getting Forbidden Attributes Error even though I have used strong parameters in Rails. I have two models: Posts and Categories.
Here is my Post Controller:
class PostsController < ApplicationController
def index
#posts=Post.all
end
def new
#post=Post.new
#category=Category.all
end
def create
#post = Post.new(params[:post])
if #post.save
redirect_to posts_path,:notice=>"Post saved"
else
render "new"
end
end
def allowed_params
params.require(:post).permit(:title, :body, :category_id)
end
end
And here is my view for posts/new:
<%= form_for #post do |f| %>
<p>
<%= f.label :title %></br>
<%= f.text_field :title%><br/>
</p>
<p>
<%= f.label :body %></br>
<%= f.text_area :body%><br/>
</p>
<p>
<%= f.select :category_id, Category.all.collect{|x| [x.name,x.id]},{:include_blank =>"Select one"}%><br/>
</p>
<p>
<%= f.submit "Add Post" %>
</p>
<% end %>
But I am still getting Error.
You need to use allowed_params instead of params[:post]:
#post = Post.new(allowed_params)
I have a 'post' controller in that I have two variable title and body which I am passing through strong parameters.But I need to use two other variable which are path and name which are in different model name 'Document'..And also I am saving the content in database ..but unable to do so..getting this error view [posts/_form.html.erb]
undefined method `name' for #
[posts_controller]
class PostsController < ApplicationController
before_action :authenticate_user!
def index
#posts = Post.user_post(current_user).order('created_at DESC').paginate(:page => params[:page], :per_page => 5)
end
def new
#post = Post.new
end
def show
#post = find_params
end
def create
#post = Post.create(post_params)
#post.user = current_user
if #post.save
redirect_to #post
else
render 'new'
end
end
def edit
#post = find_params
end
def update
#post = find_params
if #post.update(post_params)
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = find_params
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :body)
Document.new(params,:files=>[])
end
def find_params
Post.find(params[:id])
end
end
[post/_form.html.erb]
<%= form_for #post,html: { multipart: true } do |f| %>
<% if #post.errors.any? %>
<div id="errors">
<h2><%= pluralize(#post.errors.count, "error") %> prevented this post from saving:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.label :title %><br>
<%= f.text_field :title %><br>
<br>
<%= f.label :body %><br>
<%= f.text_field :body %><br>
<br>
<%= f.label :name %> <br>
<%= f.text_field :name %><br>
<br>
<br>
<%= f.label :path %><br>
<%= f.file_field :path %><br>
<%= f.submit %>
<% end %>
[document.rb]
class Document < ActiveRecord::Base
validates :name, presence: true
validates :path, presence: true
validates :resource_type, presence: true
validates :resource_id, presence: true
mount_uploader :path, PathUploader
validates :name, presence: true
# def self.abc
# params.permit(:name,:path)
# end
def initialize(params,file)
params=file[:name]
#params.permit(name =>:name,path =>:path)
end
end
undefined method `name' for #
You're referencing a non-existent attributes for your Post form:
<%= form_for #post,html: { multipart: true } do |f| %>
<%= f.label :title %><br>
<%= f.text_field :title %><br>
<br>
<%= f.label :body %><br>
<%= f.text_field :body %><br>
<%= f.submit %>
<% end %>
Remove :name & :path references.
--
If you want to pass "extra" attributes to another model, you need to use accepts_nested_attributes_for or set the params separately to your "primary" model:
#app/models/post.rb
class Post < ActiveRecord::Base
has_many :documents
accepts_nested_attributes_for :documents
end
#app/models/document.rb
class Document < ActiveRecord::Base
belongs_to :post
end
This will allow you to pass the documents as "nested" attributes of your Post model:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
#post = Post.new
#post.documents.build
end
def create
#post = Post.new post_params
#post.save
end
private
def post_params
params.require(:post).permit(:title, :body, documents_attributes: [:name, :path])
end
end
#app/views/posts/_form.html.erb
<%= form_for #post do |f| %>
<%= f.text_field :title %>
<%= f.text_area :body %>
<%= f.fields_for :documents do |d| %>
<%= d.text_field :name %>
<%= d.text_field :path %>
<% end %>
<%= f.submit %>
<% end %>
So undefined method on a model will indicate that, well, the method doesn't exist on the model. Want to see a model's methods? Post.methods. However, in this example, the column name is not defined on the model., and you're trying to tell Post that it has a name. What you need to do is nest your parameters.
While there is a ton of cleaning up that might want to focus on first, your answer is found in the accepts_nestable_attributes_for class methods, as shown here, http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html, and strong_params documentation as shown here, http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html
In your case, you want to create a new document from a post. Your permitted params hash will look like this,
params.require(:post).permit(:title, :body, :document_attributes => [:name])
Ensure that document_attributes is singular; if a person has_many pets (for example), then you'd have pets_attributes.
In your form, something that often trips people up is the builder.
<%= form_for #post do |f| %>
<%= f.text_field :title %>
<%= f.text_field :body %>
<%= f.fields_for #post.document do |document_field| %>
<%= document_field.text_field :name %>
<% end %>
<%= f.submit %>
<% end %>
Make sure that you're telling ERB that <%= f.fields_for %>, not just <% f.fields_for %>.
I can't get along with saving Students with one POST when i"m saving Project.
My Projects controller looks like:
class ProjectsController < ApplicationController
def index
#projects = Project.all
end
def new
#project = Project.new
3.times do
student = #project.students.build
end
end
def create
#project = Project.new(project_params)
#project.status = "Waiting"
# I'm not sure about these lines
#project.students.each do |student|
student = Student.new(params[:name])
end
#project.save!
redirect_to projects_path
end
private
def project_params
params.require(:project).permit(:name, :lecturer)
end
end
And a new_project view looks like:
<h1>Creating new project...</h1>
<%= form_for #project, url: projects_path do |f| %>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :lecturer %>
<%= f.text_field :lecturer %>
</p>
<p>
<%= f.fields_for :students do |s| %>
<%= s.label :name %>
<%= s.text_field :name %>
<% end %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
And my question is how to save Project and Students (assigned to it) using one form?
First, your project_params method isn't allowing the students' names to be submitted. Try something like this:
def project_params
params.require(:project).permit(:name, :lecturer, students_attributes: [ :name ] )
end
Next, in your Project model you'll need the line
accepts_nested_attributes_for :students
(You might have put it there already - but if you didn't, you'll need to.)
Now that that's done, you shouldn't need these lines in your Project#create method:
#project.students.each do |student|
student = Student.new(params[:name])
end
Because your project can now accept nested attributes for students, they should be created automatically with the project when you save it.
I have this controller
class PeopleController < ApplicationController
def new
#person = Person.new
#person.phones.new
end
# this is the action that gets called by the form
def create
render text: person_params.inspect
# #person = Person.new(person_params)
# #person.save
# redirect_to people_path
end
def index
#person = Person.all
end
private
def person_params
params.require(:person).permit(:name, phones_attributes: [ :id, :phone_number ])
end
end
and this view
<%= form_for :person, url: people_path do |f| %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<%= f.fields_for :phones do |f_phone| %>
<div class="field">
<p>
<%= f_phone.label :phone_number %><br />
<%= f_phone.text_field :phone_number %>
</p>
</div>
<% end %>
<p>
<%= f.submit %>
</p>
<% end %>
When I fill out both form fields and hit "Save Person" I only get {"name"=>"foo"} - the phone number seems to vanish.
However, when I change phones_attributes to phones I get {"name"=>"foo", "phones"=>{"phone_number"=>"123"}} (this would however cause problems with the create function.
What's wrong here?
Please note that this question is strongly related to that one: accepts_nested_attributes_for: What am I doing wrong as well as to this posting: https://groups.google.com/forum/#!topic/rubyonrails-talk/4RF_CFChua0
You don't have #phones defined in the controller:
def new
#person = Person.new
#phones = #person.phones.new
end
Finally found the problem. In the view there should be
<%= form_for #person, url: people_path do |f| %>
Instead of
<%= form_for :person, url: people_path do |f| %>
#phron said that already here:
accepts_nested_attributes_for: What am I doing wrong
class ItemController < ApplicationController
def create
item = current_user.items.build(params[:presentstem])
item.created_at = Time.now
item.save!
redirect_to root_path
end
def destroy
end
end
And my form in views/home/index/html.erb to add an item
<div id="add_item">
<p>Add a new item</p>
<% form_for Item.new do |f| %>
<div id="add_item_container">
<%= f.text_field :present %>
<%= f.text_field :stem %>
<%= f.text_field :secondary %>
<%= f.check_box :atype %>
<%= f.text_field :comment %>
</div>
<%= f.submit "Add to List" %>
<% end %>
</div>
How do I define Item?
at localhost:3000 I get
Expected /Users/user/Desktop/test/app/models/item.rb to define Item
Extracted source (around line #3):
You should have Item class definition in this file /Users/user/Desktop/test/app/models/item.rb, probably you don't...
class Item < ActiveRecord::Base
#class definition goes here
end
You are thinking wrong.
You have an model in app/models/item.rb
for this you have an controller in app/controllers/items_controller.rb
and you have views in app/views/items/template.haml
if you want to do a form_for you do the form for a object. rails is looking what type of action you want to participate (new, update) and generates automatically the route (restful).
so you just gave an object to the form_for helper
#in view
=form_for Item.new do |f|
or
#in items_controller.rb
def new
#item = Item.new
end
#in new.haml
=form_for #item