Reputation: 98
I've got an issue in Rails with the create action - I have this information in my controller:
ComputerController
def create
@computer = Computer.new(computer_params)
redirect_to computers_path
end
private
def computer_params
require.params(:computer).permit(:computer_name,
:cpu_tag,:serial,:location,:brand,:model,:ram,:cpu,:os,:warranty,:comments)
end
Then in my model I have some validations:
class Computer < ActiveRecord::Base
validates :computer_name, uniqueness: true, presence: true,
length:{maximum: 12}
validates :cpu_tag, length: {maximum: 4}, uniqueness: true,
:numericality => {:only_integer => true}
validates :serial, presence: true
validates :location, presence: true
validates :brand, presence: true
validates :model, presence: true
validates :ram, presence: true
validates :cpu, presence: true
validates :os, presence: true
validates :warranty, presence: true
validates :comments, presence: true
end
The view new.html.erb is:
<div class="row text-center">
<h2 class = "mimsinfoblackindex">Add A Computer To The Inventory </h2><hr/>
<div class="col-md-3 description_pc text-left">
<%= form_for @computer do |f|%>
<h4 class = "mimsformgreen">
<%= f.label :computer_name,'Computer Name:'%>
<%= f.text_field :computer_name%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :cpu_tag, 'Computer Tag:'%>
<%= f.text_field :cpu_tag%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :serial, 'Serial:'%>
<%= f.text_field :serial%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :location, 'Location:'%>
<%= f.text_field :location%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :brand, 'Brand:'%>
<%= f.text_field :brand%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :model, 'Model:'%>
<%= f.text_field :model%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :ram, 'Ram:'%>
<%= f.text_field :ram%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :cpu, 'Processor:'%>
<%= f.text_field :cpu %>
</h4>
<h4 class = "mimsformblack">
<%= f.label :os, 'Operating System:'%>
<%= f.text_field :os%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :warranty, 'Warranty:'%>
<%= f.text_field :warranty%>
</h4>
<h4 class = "mimsformblack">
<%= f.label :comments, 'Comments:'%>
<%= f.text_field :comments%>
</h4>
<%= f.submit 'Add The Computer'%>
<% end %>
I already did TDD for my models and I don't have any problems, but when I submit the computer form, I get an error message in the screen that says:
wrong number of arguments (0 for 1)
private
def computer_params
require.params(:computer).permit(:computer_name,:cpu_tag,
:serial,:location,:brand,:model,:ram,:cpu,:os,:warranty,:comments)
end
Upvotes: 1
Views: 87
Reputation: 76774
To add to the answer, there are some fixes you could make with your code:
When defining the same presence
validation, you can pass multiple arguments (attributes) to the method:
#app/models/computer.rb
class Computer < ActiveRecord::Base
validates :serial, :location, :brand, :model, :ram, :cpu, :os, :warranty, :comments, presence: true
end
Rails' strong params
functionality is pretty specific in stating you need to "require" a top-level param, and then "permit" its child params:
def computer_params
params.require(:computer).permit(:computer_name,:cpu_tag, :serial,:location,:brand,:model,:ram,:cpu,:os,:warranty,:comments)
end
In programming, the most efficient code wins.
This means you should not be replicating a bunch of code time & time again (using the attributes
method):
#app/views/computers/new.html.erb
<%= form_for @computer do |f| %>
<% @computer.attributes.each do |attr| %>
<% xtra = "green" if attr == :computer_name %>
<%= content_tag :h4, class: "misform #{xtra}" do %>
<%= f.label attr.to_sym, attr.titleize + ":" %>
<%= f.text_field attr.to_sym %>
<% end %>
<% end %>
<%= f.submit 'Add The Computer'%>
<% end %>
See how much cleaner that is?
You've used these two class names:
mimsformblack
mimsformgreen
Looking at my #3
recommendation, can you see how this is very inefficient? It's violates a principle called DRY (Don't Repeat Yourself), in which you're meant to use as little code with as much functionality as possible.
You can apply multiple CSS classes to each element, which means you'll be able to do the following:
<div class="mimsform">This will be black</div>
<div class="mimsform green">This will be green</div>
When you create in Rails, you have to save the object to the model:
def create
@computer = Computer.new computer_params
redirect_to computers_path if @computer.save
end
Many newbie developers don't save their new object, preventing them from actually saving the data to the db.
Upvotes: 0
Reputation: 4226
Try rewriting your computer_params
to:
private
def computer_params
params.require(:computer).permit(:computer_name, :cpu_tag, :serial, :location, :brand, :model, :ram, :cpu, :os, :warranty, :comments)
end
It appears that params
and require
are reversed in your original code.
Hope it helps!
Upvotes: 3