Save record in rails 4.0 using params hash - rails-activerecord

I'm trying to create a new record in rails using the form_for helper method. I think the params hash is blank because I keep getting blank errors when I submit the form.
This is my form:
<% provide(:title, "Add Department") %>
<h1>Add Department</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#department) do |f| %>
<%= render 'shared/department_error_messages' %>
<%= f.label :Full_Department_Title %>
<%= f.text_field :full_name %>
<%= f.label :Department_Abbreviation %>
<%= f.text_field :abbreviation %>
<%= f.submit "Add department", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
This is my departments controller
class DepartmentsController < ApplicationController
def show
#department = Department.find(params[:id])
end
def new
#department = Department.new
end
def create
#department = Department.new(params[department_params]) # Not the final implementation!
if #department.save
redirect_to root_path
else
render 'new'
end
end
private
def department_params
# This says that params[:department] is required, but inside that, only params[:department][:full_name] and
# params[:department][:abbreviation] are permitted. Unpermitted params will be stripped out
params.require(:department).permit(:full_name, :abbreviation)
end
end
This is the Model:
class Department < ActiveRecord::Base
validates :full_name, presence: true, length: { minimum: 6 }
end
When I submit, errors are rendered saying the full_name can't be blank (and the fields are now empty). The debug info is:
--- !ruby/hash:ActionController::Parameters utf8: ✓
authenticity_token: EjfYjWAzaw7YqVZAkCPZwiEMFfb2YLIRrHbH1CpZOwA=
department: !ruby/hash:ActionController::Parameters
full_name: Sports Department
abbreviation: SD
commit: Add department
action: create
controller: departments
I've also checked the development log. The transaction starts and is then rolled back. I can save a record in the console so I'm guessing its something to do with the params hash, but can't figure it out. Please help

This line:
#department = Department.new(params[department_params])
Should be:
#department = Department.new(department_params)
And, as a minor issue (but not causing this problem), your label tags should look like:
f.label :full_name, "Full Department Title"
This way they are correctly associated with the input.

Related

Ruby on Rails error when using same form on multiple pages

I have a contact form setup and working on my 'Contact' page. However, when I copy that form to another page I get this error: 'First argument in form cannot contain nil or be empty'.
Here is my contactcontroller:
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
if #contact.valid?
ContactMailer.contact_email(#contact).deliver_now
redirect_to new_contact_path, notice: "Your email has been sent. Thank you."
else
render :new
end
end
end
Here is the other page controller:
class GolfcoursesController < ApplicationController
protect_from_forgery
def index
#golf_courses = GolfCourse.all
end
def show
#golf_courses = GolfCourse.all
#golfcourse = GolfCourse.find_by(slug: params[:slug])
#holes = #golfcourse.golf_holes
end
def events
end
def membership
end
def practice_facilities
end
def contact
end
def golf
#golf_courses = GolfCourse.all
end
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
if #contact.valid?
ContactMailer.contact_email(#contact).deliver_now
redirect_to new_contact_path, notice: "Your email has been sent. Thank you."
else
render :new
end
end
end
And here is the form:
<div class="container">
<h4>Let us know if you have any questions.</h4>
<%= form_for #contact, :html => {:role => 'form'} do |f| %>
<div class="form-group">
<%= f.label :name, 'Enter your name:' %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email, 'Email:' %>
<%= f.email_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :message, 'Message:' %>
<%= f.text_area :message, class: 'form-control', :rows => 3 %>
</div>
<div class="form-group">
<%= f.submit 'Submit', class: 'btn btn-default' %>
</div>
<% end %>
</div>
Thanks in advance for any help!
'First argument in form cannot contain nil or be empty'
You should also initialize the #contact in your other controller.
If you would like to share forms, I'd suggest the use of partials and passing in locals. This makes your code also somewhat DRY.
For reference also see the rails guides:
http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

How to solve ParameterMissing error using ROR

Please help me to solve the below error.
Error:
ActionController::ParameterMissing in CustmersController#create
param is missing or the value is empty: users
When i am submitting the data,this error is coming.
My code is as follows
views/custmers/new.html.erb
<h1>Enter your data here</h1>
<center>
<%= form_for #users,:url => {:action => 'create'} do |f| %>
<% if #users.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#users.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #users.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<label for="name">Name:</label>
<%= f.text_field :name,placeholder:"Enter your name",:class => "input-field" %>
</p>
<p>
<label for="email">Email:</label>
<%= f.email_field :email,placeholder:"Enter your email",:class => "input-field" %>
</p>
<p>
<label for="phone">Phone no:</label>
<%= f.telephone_field :phoneno,placeholder:"Enter your phone number",:class => "input-field" %>
</p>
<p>
<%= f.submit "Submit" %>
</p>
<% end %>
<%= link_to "BACK",custmers_index_path %>
</center>
controller/custmers_controller.rb
class CustmersController < ApplicationController
def index
end
def new
#users=Custmer.new
end
def show
end
def create
#users=Custmer.new(user_params)
if #users.save
flash[:notice]="You have signed up successpully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="You have not signed up successfully"
flash[:color]="invalid"
render :new
end
end
private
def user_params
params.require(:users).permit(:name,:email,:phoneno)
end
end
model/custmer.rb
class Custmer < ActiveRecord::Base
EMAIL_REGEX = /\A[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\z/i
validates :name,presence:true,length: { minimum: 5 }
validates :email, :presence => true, :uniqueness => true, :format => EMAIL_REGEX
validates :phoneno, presence: true,length: {minimum: 10}
end
I am using rails version-4.2.0 and ruby version-1.9.3.Please help me to resolve this error.
If you look at the stack trace accompanying your error, you could tell definitely where the problem is -- look for the first line in the stack trace that refers to your code (and not library code).
But a fair guess is the require(:users) line in your controller. It looks like you either copy/pasted this code from another controller, or changed the name of your controller after generating it as part of your scaffold.
It should be requires(:custmer) instead, as that is the class of the thing you're submitting.
As a general approach, you should follow the standard Rails practices for naming things, throughout. If you really want to use the misspelled, Custmer class, have at it, but use #custmr inside your controller and views to refer to an instance, not #users.

Passing parent model's id to child's new and create action on rails

My project has 2 models, Company and Product. Company has many products and products belongs to company. I want to put a link to Product's new action on a Company show page and pass company_id to Product new action so that the new product automatically belongs to the company from which it linked.
How should I change below codes to make this happen?
My environment is ruby 2.0.0 and rails 4.0.2
show.html.erb(Companies)
<%= link_to "Add new product", new_product_path(company_id: #company) %>
products_controller.rb
def new
#product = Product.new(params[:company_id])
end
def create
#product = Product.new(product_params, params[:company_id])
if #product.save
flash[:success] = "Product successfully created."
redirect_to #product
else
render 'new'
end
end
new.html.erb(products)
<% provide(:title, 'New product') %>
<h1>Add a new product</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#product) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, "Product Name" %>
<%= f.text_field :name %>
<%= f.label :description, "Description" %>
<%= f.text_area :description %>
<%= f.label :type, "Product Type" %>
<%= f.text_field :type %>
<%= f.label :released_date, "Released Date" %>
<%= f.date_field :released_date %>
#I want to omit below 2 lines by passing company_id from company show action
<%= f.label :company_id, "Company ID" %>
<%= f.text_field :company_id %>
<%= f.submit "Submit", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
:comapny_id is passed to product new action as shown in URL.
http://localhost:3000/products/new?company_id=6
Also shown in debug log.
company_id: '6'
action: new
controller: products
I think your error lies in the way you create the new product in the new action. At the moment it only passes the company id itself to the constructor, but you are not telling rails wich property should be set with it.
If you change it to #product = Product.new(company_id: params[:company_id]), then your new product object should have the company id and it should be filled in in the create form. Then, instead of omitting the fields you could just use a hidden field. Like this, there is no extra field for the company_id but it is still automatically added to the product_params and #product = Product.new(product_params) will create a product with a company_id.

Can not create user with Rails app on heroku, but works perfect on localhost

So I am working through the Michael Hartl tut and this app works perfectly on the localhost but the moment I deploy to heroku it wont create a user when i submit the information. In fact it just sits there as if I just clicked on an empty screen, no error message nor a rediret. I looked at the heroku logs and there are no exceptions that I can see being logged. I tried updating the controller behavior but i get the same result. This is frustrating.
my form looks like this:
<div class="main-form">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages'%>
<%= f.label :name %>
<%= f.text_field :name, class: "active" %><br/>
<%= f.label :email %>
<%= f.text_field :email %><br/>
<%= f.label :password %>
<%= f.password_field :password %><br/>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %><br/>
</div>
<div class="actions">
<%= f.submit "create my account", class: "btn btn-lg btn-default" %>
</div>
<% end %>
my controller looks like:
class UsersController < ApplicationController
def new
end
def show
#user = User.find(params[:id])
#title = #user.name
end
def create
#title = "welcome"
#user = User.new(user_params)
if #user.password_confirmation.empty? == false
#user.save
redirect_to user_path(#user)
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
i have also tried setting up my create method like:
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render 'new'
end
end
neither of these methods worked? Any advice would be welcome.
If you inspect the page it looks like your submit button is outside of the form definition:

RoR: How can I get my microposts to show up?

Here is the users show view where they are supposed to show up. ..
<section>
<div id= "purchases">
<%= render 'shared/micropost_form_purchase' %>
</div>
<div id="sales">
<%= render 'shared/micropost_form_sale' %>
</div>
</section>
<%= #sales %> <%# This is just to see if it outputs anything. It doesn't :( %>
<div id="purchases list">
<ol class="microposts">
<%= render #purchases unless #purchases.nil? %>
</ol>
</div>
<div id="sales list">
<ol class="microposts">
<%= render #sales unless #sales.nil? %>
</ol>
</div>
so the forms (partials) are loading fine, but then when I make a post, in either one, neither the purchases list nor the sales list shows up. I checked the database and they are being created along with an entry in the column indicating kind (either sale or purchase).
Here are the forms:
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
and
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
also, here is the show part of the users_controller.rb
def show
#user = User.find(params[:id])
#micropost=Micropost.new
#microposts = #user.microposts.paginate(page: params[:page])
end
and here is the show part of the microposts_controller.rb
def show
#micropost = Micropost.find(params[:id])
#microposts = Micropost.where(:user_id => #user.id)
#purchases= #microposts.collect{ |m| m if m.kind == "purchase"}.compact
#sales = #microposts.collect{ |m| m if m.kind == "sale"}.compact
end
additionally, with the help of this post (http://stackoverflow.com/questions/12505845/ruby-error-wrong-number-of-arguments-0-for-1#12505865) the variables #microposts, #purchases, and #sales are all outputting correctly in the console.
can anyone help me out?
edit: using scopes as suggested by the answer given works in the console (it outputs everything correctly, but they still don't show up in the view. Does this mean it is something wrong with my syntax for the users show page?
edit 2:
Here is the view/microposts/_micropost.html.erb code
<li>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
confirm: "You sure?",
title: micropost.content %>
<% end %>
</li>
I'm making some assumptions without seeing more of your code, but it looks like you could
write what you've shown a little differently. I'm assuming your databases are migrating
and have the required columns, e.g., Micropost#kind, Micropost#user_id, etc.
You can use scopes to refine a collection of microposts more expressively. It might be helpful to read
up about ActiveRecord scopes: http://guides.rubyonrails.org/active_record_querying.html#scopes.
class Micropost < ActiveRecord::Base
belongs_to :user
scope :purchases, where(:kind => "purchase")
scope :sales, where(:kind => "sale")
# your code
end
I'm also assuming your user has many microposts:
class User < ActiveRecord::Base
has_many :microposts
# your code
end
For your forms, I'd suggest attaching your hidden field to the form object (f.hidden_field) so
you don't have to specify the name as 'micropost[kind]'.
<%= form_for(#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= f.hidden_field :kind, :value => "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
In MicropostsController#show, you can use your new scopes:
def show
#micropost = Micropost.find(params[:id])
#microposts = #user.microposts
#purchases = #microposts.purchases
#sales = #microposts.sales
end
You should also confirm that your MicropostsController#create action is actually adding
the microposts to the user sending the form (I'm assuming a current user method).
def create
#micropost = current_user.microposts.create(params[:micropost])
# yada
end
You can also confirm expected results on rails console after creating purchases or sales micropost with:
Micropost.purchases
Micropost.sales
Again, I could be missing something without seeing more of the code base.
Check Micropost.count, #purchases.count, #sales.count (by printing them in the controller, or some part of the view) to see if the records actually exist.
Also, if you want to render collections likes #sales and #purchases, you need to make sure that the model partial exists (_micropost.html.erb in your case). That is probably where you need to look for the view errors. For all you know, that file could be empty, thus no errors will show up at all.
The problem might also lie in your microposts#create (or whichever action that you are saving the micropost in), the micropost should be associated with the current_user:
#micropost = current_user.microposts.build(params[:micropost])
Taking this and your previous question into account, I suggest you go through the original code for the RoR tutorial again (and verify that all tests are passing) before taking it apart. You can always add new tests to it for your experiments and they will help in figuring out where you went wrong.

Resources