Ruby on Rails - undefined method `map' for nil:NilClass - ruby-on-rails

I have spent the past few hours trying to figure out what I am doing wrong, but I cannot come to a solution. Simply put, I am trying to populate a select box with data from a table called 'semesters'. (I've seen tons of questions regarding this on SO, but I cannot get them to work with my app).
Here's what I have:
Courses Controller
class CoursesController < ApplicationController
def create
#semesters = Semester.all()
#course = Course.new(params[:course])
# Save the object
if #course.save
flash[:notice] = "Course created."
redirect_to(:action => 'list')
else
# If save fails, redisplay the form so user can fix problems
render('new')
end
end
end
View
#views/courses/new.html.erb
<%= form_for(:course, :url => {:action => 'create'}) do |f| %>
<%= f.select(:semester, #semesters.map { |s| [ s.name, s.id ] }) %>
<%= submit_tag("Create Course") %>
<% end %>
I was hoping it would output:
<select>
<option id="1">Spring 2013</option>
<option id="2">Fall 2013</option>
</select>
But instead, I am getting the error:
views/courses/new.html.erb where line #32 raised:
undefined method `map' for nil:NilClass
Line #32 corresponds to my form helper select.
Any help on this would be great!

You should set your #semesters variable in controller:
def new
#semesters = Semester.all
end
The error occurs because unset instance variable is evaluated to nil, so you try to call map method on nil object.

Related

Name attribute is coming up Nil?

I am trying to create a destination, but it keeps telling me in my browser that 'name' is nil when it redirects redirects to my 'show' view.
Error I receive
undefined method `name' for nil:NilClass
Here are my controller actions for new, create, and show:
def show
#destination = Destination.find_by(id: params[:id])
end
def new
#destination = Destination.new
end
def create
#destination = Destination.create(dest_params)
redirect_to user_destination_path(current_user, #destination.id )
end
private
def dest_params
params.require(:destination).permit(:name,:user_id)
end
My new form where I enter the name of the destination:
<h2>Add a destination</h2>
<div>
<%= form_for #destination do |f|%>
<%= f.label :name %>
<%= f.text_field :name %><br>
<%= f.submit %>
<% end %>
</div>
here is my read/show view:
<h3>Added destination</h3>
<div>
<p><%= #destination.name %></p>
</div>
Before all this I was getting missing required keys [:id] errors, but I seemed to fix that but for some reason I suspect that might have something to do with the issue I am having now. Let me know if you are able to spot the issue
Updated Error
No route matches {:action=>"show", :controller=>"destinations", :id=>nil, :user_id=>"1"}, missing required keys: [:id]
The main problem here is a total lack of error handling. You're not checking at all if the user provided valid input or if the record was even saved in your create method.
def create
#destination = Destination.create(dest_params)
redirect_to user_destination_path(current_user, #destination.id )
end
If the record is not saved for example due to a failed validation #destination.id is nil.
In your show method you're using find_by instead of find which just lets the error slide instead of raising a ActiveRecord::RecordNotFound error.
Your controller should actually look like:
class DestinationsController
def show
# will raise if the record is not found and return a 404 not found response
# instead of just exploding
#destination = Destination.find(params[:id])
end
def new
#destination = Destination.new
end
def create
# never just assume that the record is created unless you want
# to get kicked in the pants.
#destination = Destination.new(dest_params)
if #destination.save
# this route really does not need to be nested.
# see https://guides.rubyonrails.org/routing.html#shallow-nesting
redirect_to user_destination_path(current_user, #destination)
else
# re-render the form with errors
render :new
end
end
private
def dest_params
params.require(:destination).permit(:name,:user_id)
end
end

Rails 5 – Can't update single attribute with link_to, undefined method `to_sym'

I'm trying to archive a Product by using a link_to in Rails 5.
In the view:
<% #products.each do |product| %>
<%= link_to product_path(product, "product[archived]" => true),
:method => :put,
data: { confirm: 'Sure?' } do %>
<i class="fa fa-archive color-danger" aria-hidden="true"></i>
<% end %>
<% end %>
But after clicking on the link my ProductsController throws the following error:
undefined method `to_sym' for {:archived=>false}:Hash Did you mean? to_s to_yaml to_set
The error points to the if #product.update(product_params) line. Full update method is:
def update
#product = Product.find(params[:id])
puts #product.id
if #product.update(product_params)
redirect_to #product
else
render 'edit'
end
end
EDIT
Actually the offending line was a badly written validation in my Product model.
I had: validates_uniqueness_of :code, :scope => [:archived => false], where it should have been validates_uniqueness_of :code, conditions: -> { where.not(archived: true) }.
In hindsight it was a silly mistake, but now I'm wondering why it was throwing such a strange error and worse, the error was in the controller...
The scope attribute on the validation is expecting either a single attribute or an array of attributes from your model, something like
class Product < ApplicationRecord
validates_uniqueness_of :code, :scope => :archived
end
As it turns out, including the :scope option adds a where clause during the validation which looks like where(:archived => false) based on my example above.
From your original code validates_uniquesness_of :code, :scope => { :archived => false }, this results in the scope executing where({:archived => false} => nil). You can see that the hash argument to where is definitely off.
Later in the stack, ActiveRecord is going to try to turn the key from the argument hash into a symbol with to_sym and look for that key as an attribute on the Product model. However, the key in this case is the hash {:archived=>false} which does not respond to to_sym, and here the undefined method error gets raised.
The reason the error "appeared" in the controller is because the line product.update(product_params) in your controller is the beginning of the call chain that led to the bad validation being called in the model, which you have determined was the source of the error.

Simple CRUD won't create Object

I have tried to get into rails and ruby by starting to work on a little project and have a problem I can't get around.
As I was trying to create a simple CRUD for an Object, the creation part made no sense anymore.
def create
if (params.nil? || params[:board].nil?)
return render status: 400
end
#board = Board.create(params["board"]["title"], params["board"]["description"])
#...
end
For whatever reason, it gives me an ArgumentError "wrong number of arguments (given 2, expected 0..1)". So I thought I'll simply create it myself and use the save-Method to save it into the database, but that didn't work out either:
#board = Board.new(params["board"]["title"], params["board"]["description"])
#board.save!
This gives me the NoMethodError "undefined method `reverse_merge!' for nil:NilClass".
I tried allot of debugging now but can't figure it out. And not, it's not nil, even though it's saying it's using the NilClass.
EDIT: Form Code (View)
<%= form_tag :action => 'create' do %>
<div class="fluid-container">
<p><label for="board_title">Title</label></p>
<%= text_field 'board', 'title' %>
</div>
<div class="fluid-container">
<p><label for="board_description">Description</label></p>
<%= text_area 'board', 'description' %>
</div>
<%= submit_tag %>
<% end %>
I really don't know what's going on, hopefully someone can help. Thanks in advance - PreFiX/Dominik
Instead of
#board = Board.create(params["board"]["title"], params["board"]["description"])
try
#board = Board.create(title: params["board"]["title"], description: params["board"]["description"])
You should be able to do this too
#board = Board.create(params[:board])
but for security reasons that wont work
http://api.rubyonrails.org/classes/ActionController/Parameters.html
When you try to create a new object, you should pass a hash and not strings like you did.
Replace your controller method to
def create
#board = Board.new(board_params)
if #board.save
redirect_to #board, notice: 'Board was successfully created.'
else
# render the new page
end
end
And add a private method
private
def board_params
params.require(:board).permit(:title, :description)
end

Ruby on rails can't create with params

I have a from created in Ruby on rails. The code the form looks like this:
<%= simple_form_for(#action) do |f|%>
<%= render 'shared/error_messages' %>
<%=f.label :action_name, "Action name"%>
<%=f.text_field :action_name%></br>
<%=f.input :startDate,:as => :datetime_picker, :label =>"Start date"%>
<%=f.input :endDate,:as => :datetime_picker, :label =>"End date"%>
<%=f.label :contentURL, "Content url"%>
<%=f.text_field :contentURL%></br>
<%= f.button :submit, class: "btn btn-large btn-primary" %>
<%end%>
But when I click the submit button I get this error:
undefined method `permit' for "create":String
def action_params
params.require(:action).permit(:action_name, :startDate,:endDate,:contentURL)
All other forms a working ok, I guess it is something really obvious, just can't see it :(
I really appreciate any help, solving this problem.
Thanks!!
EDIT:
Controller code:
def create
action = Action.new(action_params)
if #action.save
flash[:success] = "New Action saved"
redirect_to "/"
else
render 'new'
end
end
private
def action_params
params.require(:action).permit(:action_name, :startDate,:endDate,:contentURL)
end
In Rails 4, you must use Strong Parameters in your controllers. Here's some explanation from the official blog. And some example:
class PeopleController < ActionController::Base
# This will raise an ActiveModel::ForbiddenAttributes exception because it's using mass assignment
# without an explicit permit step.
def create
Person.create(params[:person])
end
# This will pass with flying colors as long as there's a person key in the parameters, otherwise
# it'll raise a ActionController::MissingParameter exception, which will get caught by
# ActionController::Base and turned into that 400 Bad Request reply.
def update
redirect_to current_account.people.find(params[:id]).tap do |person|
person.update_attributes!(person_params)
end
end
private
# Using a private method to encapsulate the permissible parameters is just a good pattern
# since you'll be able to reuse the same permit list between create and update. Also, you
# can specialize this method with per-user checking of permissible attributes.
def person_params
params.required(:person).permit(:name, :age)
end
end
Notice how, in the last lines, under the private keyword, the person_params method is defined, which declares the permitted fields to be assigned by the create and update methods on top. And it's the person_params that is used for updating - the valid example - instead of the raw params array.

RoR - undefined method `merge'

I'm studing Ruby on Rails with the "RoR Bible" by Thimothy Fisher. But one of the examples doesn't work. It's code - http://pastebin.com/gtjLsdt0
The error is: NoMethodError in Contact#new where line #4 raised:
undefined method `merge' for "first_name":String
that's my contact_controller. I'm just retyping example's code, and there weren't any words about merge
class ContactController < ApplicationController
def index
#contacts = Contact.find(:all);
end
def show
end
def new
#contact = Contact.new;
end
def create
end
def update
end
end
What is wrong??
Lol that example is completely wrong!
Instead of writing sth like this:
<%= f.text_field 'contact', 'first_name' %>
You should write
<%= f.text_field :first_name %>
Because by using f.field_type you assign the field to the :contact form which provides the f methods by iteration! Also you can write
<%= f.label :first_name, "description of first_name" %>
Instead of writing it manual!
// I loked up the book you refered it seems to be quit outdated. You may buy "The Rails 3 Way" or sth. that can hold up to the current rails version!

Resources