Easy way of dealing with nil properties in templates?


#1

Is there an easy way to deal with nil properties in
templates? All I’m aware of are these methods, and
it’s quite tedious and surely violates DRY.

<%= @member.name unless @member.name.nil? %>
<%= @member.name.to_is %>
<%= “#{@member.name}” %>

csn


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#2

Yeah. You can also put begin/end around templates,
actions, probably handle a nil exception in
rescue_action_in_public, or even have database
defaults be ‘’ rather than null, but I’m not keen on
any of those either.

csn

— Kelly Dwight F. removed_email_address@domain.invalid
wrote:

And if I see it enough I will move it into a helper.
in



Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#3

Hmmm. I don’t have much of an improvement. I tend to use

?:

Instead of your methods I would put

<%= @member.name.nil? ? ‘’ : h(@member.name) http://member.name/ %>

And if I see it enough I will move it into a helper.

But I agree, it is tedious.

-Kelly


#4

You can also do this although I don’t think its any prettier :wink:

<%= @member.name rescue nil %>

-Ezra

On Feb 6, 2006, at 7:53 PM, Kelly Dwight F. wrote:

But I agree, it is tedious.
<%= @member.name.to_is %>
Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails

-Ezra Z.
WebMaster
Yakima Herald-Republic Newspaper
removed_email_address@domain.invalid
509-577-7732


#5

This is the one thing I miss about perls Template-Toolkit. If you
access an undefined value then nothings prints and you don’t get an
error. I wish there was a way in a configuration file to make erb act
this way.


#6

CSN wrote:

I’m a bit puzzled by your question: <%= @member.name %> will produce the
Erb code _erbout.concat((@member.name).to_s) which, since nil.to_s ==
“”, will result in “” being appended to _erbout.

Did you mean @member == nil?
Or defined?(@member)==false?
Or @member.has_attribute?(“name”) == false?

– stefan


For rails performance tuning, see: http://railsexpress.de/blog
Subscription: http://railsexpress.de/blog/xml/rss20/feed.xml


#7

Kelly Dwight F. wrote:

Often you have some base record, with an association to another record
and
you need an attribute. For example, say you have a project task and you
want
to display the name of the person responsible – you might have:

@task.user.login

If user is undefined then you are trying to do a .login on a nil object.

You could override method_missing for NilClass to simply return nil when
an unknown method is called on nil.

Then something like…

<%= @member.name %>

will do nothing if @member==nil

require ‘pp’
class NilClass
def method_missing(*params)
return nil
end
end

pp @member.name #=> nil if @member.name not defined

This also helps with nested hashes

a= {:test=>“test”}
pp a[:test] #=> “test”
pp a[:test][:one] #=> nil
pp a[:one] #=> nil

This might have all sorts of other unintended side effects… I haven’t
tested it completely.

_Kevin


#8

Kelly Dwight F. wrote:

Often you have some base record, with an association to another record and
you need an attribute. For example, say you have a project task and you want
to display the name of the person responsible – you might have:

@task.user.login

If user is undefined then you are trying to do a .login on a nil object.

<%= task.user.login rescue nil %>

seems to do the job.

– stefan


For rails performance tuning, see: http://railsexpress.de/blog
Subscription: http://railsexpress.de/blog/xml/rss20/feed.xml


#9

Kevin O. wrote:

If user is undefined then you are trying to do a .login on a nil object.

You could override method_missing for NilClass to simply return nil when
an unknown method is called on nil.

don’t do this. It screws up nil’s semantics big time.

– stefan


For rails performance tuning, see: http://railsexpress.de/blog
Subscription: http://railsexpress.de/blog/xml/rss20/feed.xml


#10

Often you have some base record, with an association to another record
and
you need an attribute. For example, say you have a project task and you
want
to display the name of the person responsible – you might have:

@task.user.login

If user is undefined then you are trying to do a .login on a nil object.


#11

From: charlie bowman <cbowmanschool@…>
Subject: Re: Easy way of dealing with nil properties
in templates?
Date: 2006-02-07 15:53:59 GMT (1 hour and 55 minutes
ago)

This is the one thing I miss about perls
Template-Toolkit. If you
access an undefined value then nothings prints and
you don’t get an
error. I wish there was a way in a configuration
file to make erb act
this way.

Yeah, some Rails var like
‘convert_nil_properties_to_strings’ would be nice. But
then I’d also want nil METHODS and nil objects to
cause errors.

csn


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#12

CSN wrote:

Is there an easy way to deal with nil properties
in
templates? All I’m aware of are these methods, and
it’s quite tedious and surely violates DRY.

<%= @member.name unless @member.name.nil? %>
<%= @member.name.to_is %>
<%= “#{@member.name}” %>

Hmm, maybe a helper function would be better.
Something like (np = nil print):

<%=np @member.name %>

I’m not sure what the ‘np’ function would look like.
Anybody?

csn


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#13

Another way to handle this is to check for nil in your controller and
create
a proxy object to handle it. You don’t have to save it so it shouldn’t
change your model.

Bob S.
http://www.railtie.net/


#14

— Stefan K. removed_email_address@domain.invalid wrote:

CSN wrote:

Is there an easy way to deal with nil properties
in
templates? All I’m aware of are these methods, and
it’s quite tedious and surely violates DRY.

<%= @member.name unless @member.name.nil? %>
<%= @member.name.to_is %>
<%= “#{@member.name}” %>

I’m a bit puzzled by your question: <%= @member.name
%> will produce the
Erb code _erbout.concat((@member.name).to_s) which,
since nil.to_s ==
“”, will result in “” being appended to _erbout.

That doesn’t seem to be the case for me. ‘name’ is
null in the members table, and this causes a nil
error:

<%= @member.name %>

csn

Did you mean @member == nil?
Or defined?(@member)==false?
Or @member.has_attribute?(“name”) == false?


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#15

Cool :). Small change:

def default(string=’’)
begin
yield
rescue
string
end
end

That way, this should work too:

<%= default { @post.comment.title } %>

csn

— Ezra Z. removed_email_address@domain.invalid wrote:

<%= @member.name unless @member.name.nil? %>
Anybody?
block.
Then you call it like this:
fe:
=> [1, 2, 3, 4]
WebMaster


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


#16

CSN wrote:

And if I see it enough I will move it into a helper.

But I agree, it is tedious.

-Kelly

If something can come back nil. and it causes trouble I tend to use
<% $name = (@member.name) ? @member.name:"" %>

then use the ‘$name’ instead. But I have found that most times RoR
handles the ‘nil’ conditions just fine.


#17

Neil D. wrote :
| If something can come back nil. and it causes trouble I tend to use
| <% $name = (@member.name) ? @member.name:"" %>
|
| then use the ‘$name’ instead. But I have found that most times RoR
| handles the ‘nil’ conditions just fine.

It can be simplified into:

<% $name = @member.name || “” %>


Frederick R. aka Sleeper – removed_email_address@domain.invalid

Use variable names that mean something.
- The Elements of Programming Style (Kernighan & Plaugher)


#18

On Feb 7, 2006, at 9:59 AM, CSN wrote:

Hmm, maybe a helper function would be better.
Something like (np = nil print):

<%=np @member.name %>

I’m not sure what the ‘np’ function would look like.
Anybody?

csn

CSN-

Here is a helper method that you can put in application_helper. It

will print the default value only if the block results in nil
otherwise it will print the statement inside the block.

def default(string=nil)
begin
yield
rescue
string
end
end

Then you call it like this:

<%= default(“Title Unavailable”) { @post.comment.title } %>

If @post.comment.title throws a nil error, it will return Title

Unavailable. But if @post.comment.title is not nil it will print its
contens.

fe:

irb(main):018:0> def default(string=nil)
irb(main):019:1> begin
irb(main):020:2* yield
irb(main):021:2> rescue
irb(main):022:2> string
irb(main):023:2> end
irb(main):024:1> end
=> nil
irb(main):025:0> bar = [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):026:0> default(“No Bars!”) { bar.size }
=> 4
irb(main):027:0> default(“No Bars!”) { bar.im_with_stupid }
=> “No Bars!”

Cheers-

-Ezra Z.
Yakima Herald-Republic
WebMaster
http://yakimaherald.com
509-577-7732
removed_email_address@domain.invalid