I’m a Java refugee, who is a bit of a Ruby and Rails noob, but I’m
certainly enjoying myself and have had a bit of success in creating a
few RoR bits and pieces… however, I think I must be missing something.
I just get the feeling that, although I’ve read through a couple of good
books, there is something quite basic in RoR that I’m just not
‘getting’. So, here is a (mildly contrived) example of the sort of thing
I’ve been trying to do - maybe some experts out there could
metaphorically slap me on the back of the head and say “Duh!”
Firstly, I have a simple model:
create_table :uris do |t|
t.column :loc, :string, :null => false
create_table :links do |t|
t.column :uri_id, :integer, :null => false
t.column :text, :string, :null => false
t.column :color, :string
I’ve then used generate scaffold_resource to create the usual default
files, to which, I’ve made the following changes
class Uri < ActiveRecord::Base
class Link < ActiveRecord::Base
<% form_for(:link, :url => links_path) do |f| %>
Text: <%= f.text_field :text %><% fields_for :uri do |u| %>
URL: <%= u.text_field :loc %><% end %>
Color: <%= f.text_field :color %>
<%= submit_tag "Create" %><% end %> ...
<% form_for(:uri, :url => uris_path) do |f| %>
URI Loc: <%= f.text_field :loc %>
<%= submit_tag "Create" %><% end %> ...
This seems to be working OK, although I’m fairly sure I’ve not gone
about it quite the right way (in terms of the best way of writing the
views and controller to manipulate the Uri model and it’s relationship
If anyone has any comments on that, I’m all ears! But anyway, at least
Incidentally, my Uri view didn’t work when I originally named the Uri
model Url… it failed at the line <% form_for(:url, :url => links_path)
do |f| %>. I’m guess some sort of naming conflict… any ideas what I
should have done on that, apart from changing the name of my model?
What I’m really struggling with, though, is this: I want to have default
values for my attributes. That is, values that a new Link object would
default to when it is instantiated. These would show up on the form when
a user asks to create a new object.
For a while, I tried using the before_create filter, but had no joy
until I realised that this inserts the default values if the attributes
are empty before saving the record to the database, which is too late
So, the most obvious place, I thought, was the initialize methods:
This doesn’t work. I’ve no idea why, it looks like it should work. I’m
setting the instance variables to a default value, yet when the “new”
form is displayed, the fields are blank.
I played around with a couple more permutations of this, but to no
The best that happens is that a) no default values are displayed, and b)
I get “wrong number of arguments (1 for 0)” when the create method is
My next effort was to add my own reader methods:
@color || “#999999”
@text || “default text”
No joy here either. Again, it looks to me like these should work… I
don’t understand why they don’t. They system appears to be acting as
though these variables aren’t used, and/or these methods aren’t called,
but the way I understand everything I’ve read says that they are! I’m
sure they are - I’ve seen “password” and “password=” methods
overwritten in several different examples so that a hashed password can
be created and saved to the DB.
So, my next thought is that maybe whatever ActiveRecord sets @color to
does not evaluate to false, so my code always returns @color, and never
does not work either! Argh! In fact, now the following happens: I try to
create a new link. The form is displayed with no defaults. I enter some
values, and the object seems to be created properly. However, the value
“#999999” is displayed when I use the “show” view, and the value I
actually entered is displayed when I display the “edit” view.
OK, so IIRC, my next attempt was using something along the lines of
Text: <%= f.text_field :text, :value=>"default text" %>Which looked promising until I wanted to use the same _partial files for both the edit and create methods... in which case, "default text" shows up even when editing an object that already has a value for that attribute.
After much googling, I came across another idea. For some reason not
clear to me, this should work:
self[:text] or “default text”
It doesn’t seem to work for me either. I’m not sure why it would, but
the blog I read it on seemed to think it did work, and so did the
comments on the blog, so I’ve no idea what I’m doing wrong.
Ho hum… My next idea is to set these default values in the controller.
This seems wrong to me - default values for a model ought to be defined
in the model, shouldn’t they? But by now, I just want to get the thing
working even if its not where I think it ought to be!
so, my next attempt is:
@link = Link.new
@link.text=‘link_controller default text’
Yay! That worked. It’s not, IMO, the right place to put the code, but it
works, so I’m putting up with it for now…
But how do I get a default value for the Uri?
I try adding this line to my “new” method:
@link.uri = Uri.new(:loc=>‘www.example.com/example.html’)
It doesn’t work. At this point, I’m all out of ideas, and this is where
I decided that my understanding just has a big whole in it that needs
filling, so I’ve written this long post!
Whatever it is that I’m not ‘getting’, I think its causing me other
problems too. For example, if have a list of languages, and want to have
a select box to assign a language to a link, I’d assume that at some
point the “language_id=” method would get called, so I write:
or any number of permutations of this sort of thing, none of which are
wiping the scowl off my face!
Thanks for taking the time to read down this far in the post, and any
advice is much appreciated!