undefined method `parameterize' for nil:NilClass - ruby-on-rails

I've been trying to do SEO friendly urls, and managed to get it work, but when I call index action on blogs, I get a weird "undefined method `parameterize' for nil:NilClass." The method works when using show method.
#model
def to_s
title
end
def to_param
"#{id}-#{to_s.parameterize}"
end
#controller
#blogs = Blog.find.all
Screenshot of error
http://www.freeimagehosting.net/image.php?83e76a260b.png

Turns out you can't call title.parameterize on to_param without error. So I added a permalink column and called parameterize on that.
#models/blog.rb
before_save :permalink
def to_param
"#{id}-#{permalink}"
end
def permalink
self.permalink = self.title.parameterize
end
And voila. I knew it was something really stupid.

In case anyone is having trouble with this in Rails 5....I left out the #to_s part, which is critical.
class Post < ApplicationRecord
def to_param
slug
end
def slug
"#{id}-#{pretty_url}"
end
def pretty_url
title.to_s.parameterize
end
end

Related

Is there are way that model methods can work with variable with out them being explicitly passed?

I know this sounds like a ridiculous question but I trying to solve a chalange given by an potential employer. I have a schema and a couple of models with their methods. Almost all the methods have no variables passed in. Meaning none of the methods look like this:
def this_is_my_method(variable)
#stuff
end
or
def this_is_my_method variable
#stuff
end
but there are methods that are clearly working with variables like this:
def build_address
if variable
# do something
end
end
Is there a RoR way that a model method will just know about certain parameters or variables in certain situations?
So if my controller was recieving params that looked like this:
?my_method[begin]=1&my_method[end]=5
would the model method "my_method" know what "begin" and "end" where?
def my_method
if self.begin == self.end
# do something
else
# do something else
end
end
Remember that a model method has access to all the attributes (and other methods) of that model instance.
So (for example) this would be a valid model method.
class User < ActiveRecord::Base
def full_name
[first_name, last_name].join(' ')
end
end
This is taking an attribute user.first_name and an attribute user.last_name and combining them to create a new method user.full_name
EDIT as #Sanket has suggested you can pass values into a model if you make them attribute accessor...
def SomeController < ApplicationController
def some_controller_method
#user = User.find(params[:id])
#user.begin = params[:begin]
#user.end = params[:end]
#user.some_model_method
end
end
def User < ActiveRecord::Base
attr_accessor :begin, :end
def some_model_method
if self.begin == self.end
# do something
else
# do something else
end
end
end
Although to be frank I'd rather just pass the values in as method arguments.

NoMethodError (undefined method) however class method is defined

I have created a new class Project which is inherited from ActiveRecord::Base. I defined a class method called get_all and I would like to use in Controller but I got NoMethodError (undefined method for ...)
Model:
class Project < ActiveRecord::Base
def self.get_all
find(:all)
end
end
Controller:
class Controller < ApplicationController
unloadable
def index
#projects = Project.get_all
end
end
Note that in rails 3 the find(:all) method ( without any options ) is deprecated in favor of the all method. More about it:
http://m.onkey.org/active-record-query-interface
Also, I don't know why are you making that function, when you could just do:
#projects = Project.all
just like chrisbulmer said.
This should work:
Project model
def self.get_all
Project.all
end

Rails model methods availability in Controller

I have a method in my model which should detect the User Agent. How can I make it available to all my controller methods?
Model:
def is_iphone_request?
if request.user_agent =~ /iPhone/
return true
end
end
Controller (throws an error):
def index
#user_agent = is_iphone_request?
end
How can I achieve this? Any help is much appreciated.
Put the method in your ApplicationController instead of in a model.
I'm not sure why you've put the request user-agent check on the model--it seems like a controller centric behavior. And there is a request attribute IN a controller that you can use.
Though request will not be available in the model (you will get a NameError with the following code), your current problem is that the controller is throwing a NoMethodError because you are missing self. on the method definition. Make it a class method (by adding self.):
class MyModel < ActiveRecord::Base
def self.is_iphone_request?
if request.user_agent =~ /iPhone/
return true
end
end
Then, in your controller, you can use:
MyModel.is_iphone_request?
But like I said, you will get a NameError because request is not available in the model.
Your method is_iphone_request? should probably live in your ApplicationController (where it can be a regular private method). You can also trim it down:
class ApplicationController < ActionController::Base
...
private
def is_iphone_request?
request.user_agent =~ /iPhone/ ? true : false
end
end
Then, in your controller, you can use:
is_iphone_request?

How to modify a record before saving on Ruby on Rails

Looking for a way to either:
Change one of the fields of a new record (namely - force it to lower-case) before saving it to a RoR db.
I've tried:
before_create do |term|
term.myfield.downcase!
end
but this gives an error of:
undefined method `before_create' for RowsController:Class
or
Check that the field is all lowercase, and if not, raise an error message, and not create the record.
tried:
before_filter :check_lowcase, :only => [:new]
def check_lowcase
if (Term.new =~ /[^a-z]+/)
flash[:notice] = "Sorry, must use lowercase"
redirect_to terms_path
end
end
this seems to just be ignored....
You need to do it on your model, not your controller:
class YourModel < ActiveRecord::Base
before_create :downcase_stuff
private
def downcase_stuff
self.myfield.downcase!
end
end
before_create :lower_case_fields
def lower_case_fields
self.myfield.downcase!
end
before_save { |classname| classname.myfield = myfield.downcase }

How to use parameterize in Rails?

I want to convert the title of a page to a friendly URL and store it in the database as a permalink. My problem is I can't use the parameterize method. It's not working. Other inflections are working like upcase or downcase but parameterize is not working. Is there a special case for parameterize?
This is my code:
Controller:
def create
params[:page][:permalink] = params[:page][:title].dup
#page = Page.new(params[:page])
end
Model:
class Page < ActiveRecord::Base
before_save :makeitpermalink
before_update :makeitpermalink
private
def makeitpermalink
permalink.parameterize!
end
end
According to the Rails' documentation, there is no bang (exclamation mark) version of the parameterize method, so try removing it:
def make_it_permalink
self.permalink = self.permalink.parameterize
end

Resources