Here's a word of caution to those using inheritance and calling super in the initialize method. Consider this:
def initialize(name, price)
super
@name = name
@price = price
end
Which parent method does it call? I was surprised to find out that without () after super, it automatically calls the initialize in the parent that has the parameters (name, price), rather than the one without parameters. If your intention was to call the parent's initialize without parameters, than you must do:
super()
W
Tuesday, September 30, 2008
Monday, September 29, 2008
TinyMCE: enforce maxlength
TinyMce doesn't have support for maxlength, and putting maxlength in the textfield tag won't do anything either.
If you try to google for a solution, you might come across this site
Don't waste your time on it, because the solution is built with the old tinymce api, it wouldn't work. Instead, use the solution from this post.
J
If you try to google for a solution, you might come across this site
Don't waste your time on it, because the solution is built with the old tinymce api, it wouldn't work. Instead, use the solution from this post.
J
RoR: attr_accessible with attachment_fu
If you try to use attr_accessible on any model with attachment_fu plugin,
you'll get an error.
This article explains why
J
you'll get an error.
This article explains why
J
Sunday, September 28, 2008
RoR: attr_accessible
In a previous post, I talked about mass assignment. Well, there's something I discovered recently. If you have a polymorphic relationship, your model will have two columns: taggable_type and taggable_id. If you want to make these available for mass assignment, you cannot do:
attr_accessible taggable_type, taggable_id
Instead, RoR treats them like one attribute like so:
attr_accessible taggable
W
attr_accessible taggable_type, taggable_id
Instead, RoR treats them like one attribute like so:
attr_accessible taggable
W
Saturday, September 27, 2008
RoR Generate + SVN
We all know about RoR's ability to generate controllers, models, migrations, etc. However, if you're using a repository, you have to manually add these newly created files. This could be a pain in the ass!
Here's a tip. If you're using SVN, you'll love this. Simply add the flag --svn and the generator will automatically add the newly created files to SVN. Simple!
W
Here's a tip. If you're using SVN, you'll love this. Simply add the flag --svn and the generator will automatically add the newly created files to SVN. Simple!
W
Thursday, September 25, 2008
RoR: Mass Assignment Security
In RoR, it is possible to do something called mass assignments. For instance, when submitting a form, all the parameters are put into a params hash so you can do the following:
Product.create(params[:product])
product.update_attributes(params[:product])
Very simple, but by default, there is a security flaw. That flaw is covered in this post. If you are concerned about this, the easiest way would be to make it so that all your models will require attr_accessible on any attributes that you want mass assignment for. This then protects any attributes not listed by default.
In your config files, preferably in your initializers folder, add the following to protect all attributes:
ActiveRecord::Base.send(:attr_accessible, nil)
Then go through each model and think about which attributes should be exposed to mass assignments. For those that are not accessible, you must do the following to assign values:
product.store_id = store.id
This makes the assignment explicit and cannot be manipulated by the users.
Now that you know, go secure your applications!
W
Product.create(params[:product])
product.update_attributes(params[:product])
Very simple, but by default, there is a security flaw. That flaw is covered in this post. If you are concerned about this, the easiest way would be to make it so that all your models will require attr_accessible on any attributes that you want mass assignment for. This then protects any attributes not listed by default.
In your config files, preferably in your initializers folder, add the following to protect all attributes:
ActiveRecord::Base.send(:attr_accessible, nil)
Then go through each model and think about which attributes should be exposed to mass assignments. For those that are not accessible, you must do the following to assign values:
product.store_id = store.id
This makes the assignment explicit and cannot be manipulated by the users.
Now that you know, go secure your applications!
W
Tuesday, September 23, 2008
Stack and Queue Implementation
Array in Ruby already has built in push and pop function you can use, but if you want to make it more strict and idiot proof, here's how you can implement it.
class Stack
def initialize
@stack = []
end
def push(x)
@stack.push(x)
end
def pop
@stack.pop unless is_empty?
end
def peek
@stack.last
end
def is_empty?
@stack.empty?
end
end
class Queue
def initialize
@queue = []
end
def enqueue(x)
@queue << x
end
def dequeue(x)
@queue.shift
end
def peek
@queue.first
end
def is_empty?
@queue.empty?
end
end
J
class Stack
def initialize
@stack = []
end
def push(x)
@stack.push(x)
end
def pop
@stack.pop unless is_empty?
end
def peek
@stack.last
end
def is_empty?
@stack.empty?
end
end
class Queue
def initialize
@queue = []
end
def enqueue(x)
@queue << x
end
def dequeue(x)
@queue.shift
end
def peek
@queue.first
end
def is_empty?
@queue.empty?
end
end
J
Fun with String
This is why Ruby is amazing :D
1. converting strings to numbers
"123".to_i => 123
Duh, everyone knows that
but how bout
"123stfu".to_i => 123
or
" 123stfu ".to_i => 123
you can even indicate the base of your conversion
"111".to_i(2) => 7 # treat it as a binary number
"111".to_i(8) => 73 # treat it as an octal
split a string and convert it to an interger
"123 456 789".split.map {|m| m.to_i} => [123, 456, 789]
2. Replacing text
we can implement the lame rot13 encryption scheme in one line :)
class String; def rot13; self.tr("A-Ma-mN-Zn-z", "N-Zn-zA-Ma-m");end;end
"Please hide this line".rot13 => "Cyrnfr uvqr guvf yvar"
3. Counting Characters
s1 = "abcabcabcde"
s1.count("c") => 3
s1.count("abc") => 9
s1.count(s1) => 11
count can handle negation
s1.count("^abc") => 2
s1.count("^a") => 8
and range of chars
s1.count("a-c") => 9
s1.count("^a-z") => 0
4. Reversing a String
Microsoft loves to ask interviewee to reverse the word order of a String during an interview, it takes around 15 - 20 lines to implement the function in Java or C++, but we can do it in one :)
phrase = "This is a joke"
phrase.split.reverse.join(" ") => "joke a is This"
so next time you goto an interview, asks if they'll let you do it in Ruby ;)
5. Removing Duplicate Characters
string = "aaaaaaaaaaaaaaaaaaa".squeeze => "a"
string = "aaaaaaaaaaaaaaaaaaB".squeeze => "aB"
string = "hehe....".squeeze(".") => "hehe."
J
1. converting strings to numbers
"123".to_i => 123
Duh, everyone knows that
but how bout
"123stfu".to_i => 123
or
" 123stfu ".to_i => 123
you can even indicate the base of your conversion
"111".to_i(2) => 7 # treat it as a binary number
"111".to_i(8) => 73 # treat it as an octal
split a string and convert it to an interger
"123 456 789".split.map {|m| m.to_i} => [123, 456, 789]
2. Replacing text
we can implement the lame rot13 encryption scheme in one line :)
class String; def rot13; self.tr("A-Ma-mN-Zn-z", "N-Zn-zA-Ma-m");end;end
"Please hide this line".rot13 => "Cyrnfr uvqr guvf yvar"
3. Counting Characters
s1 = "abcabcabcde"
s1.count("c") => 3
s1.count("abc") => 9
s1.count(s1) => 11
count can handle negation
s1.count("^abc") => 2
s1.count("^a") => 8
and range of chars
s1.count("a-c") => 9
s1.count("^a-z") => 0
4. Reversing a String
Microsoft loves to ask interviewee to reverse the word order of a String during an interview, it takes around 15 - 20 lines to implement the function in Java or C++, but we can do it in one :)
phrase = "This is a joke"
phrase.split.reverse.join(" ") => "joke a is This"
so next time you goto an interview, asks if they'll let you do it in Ruby ;)
5. Removing Duplicate Characters
string = "aaaaaaaaaaaaaaaaaaa".squeeze => "a"
string = "aaaaaaaaaaaaaaaaaaB".squeeze => "aB"
string = "hehe....".squeeze(".") => "hehe."
J
List of reflective methods
I find the following commands very useful from time to time, but I kept forgetting their names. So I'm creating this post to help remind myself.
a.class
# returns the class of an object a
a.superclass
# returns the superclass of an object a
a.instance_of? A
# determines if a.class == A
a.is_a? A
#determines whether a is an instance of c, or of any of its subclass, or of any modules.
a.respond_to? :something
#determines if a has a public or protected method with the specified name.
J
a.class
# returns the class of an object a
a.superclass
# returns the superclass of an object a
a.instance_of? A
# determines if a.class == A
a.is_a? A
#determines whether a is an instance of c, or of any of its subclass, or of any modules.
a.respond_to? :something
#determines if a has a public or protected method with the specified name.
J
Shuffling an Array
I just found a very interesting article about shuffling an array correctly!
http://adrianquark.blogspot.com/2008/09/how-to-shuffle-array-correctly.html
Enjoy!
W
http://adrianquark.blogspot.com/2008/09/how-to-shuffle-array-correctly.html
Enjoy!
W
Monday, September 22, 2008
Duck Typing and Type Checking
Consider the following example:
class A
attr_accessor :x
def initialize
@x = 0
end
def +(other)
a = A.new
a.x = @x + other.x
return a
end
end
class B
attr_accessor :x
def initialize
@x = 0
end
end
a = A.new
a.x = 10
b = B.new
b.x = 5
puts (a+b).x # this will return 15
Ruby is a very dynamic language, the addition function doesn't care if the argument passed in is of type A, as long as it looks and behaves like A. This is called duck typing, name after the phase "if it walks like a duck and quacks like a duck, it must be a duck!"
if you want to ensure the object passed into the + function has to have an x accessor, you can add this to def +(other)
raise "error" unless other.respond_to? :x
or if you want to ensure object passed into the + function has to be of class A, you can add this instead:
raise "error" unless other.is_a? A
J
class A
attr_accessor :x
def initialize
@x = 0
end
def +(other)
a = A.new
a.x = @x + other.x
return a
end
end
class B
attr_accessor :x
def initialize
@x = 0
end
end
a = A.new
a.x = 10
b = B.new
b.x = 5
puts (a+b).x # this will return 15
Ruby is a very dynamic language, the addition function doesn't care if the argument passed in is of type A, as long as it looks and behaves like A. This is called duck typing, name after the phase "if it walks like a duck and quacks like a duck, it must be a duck!"
if you want to ensure the object passed into the + function has to have an x accessor, you can add this to def +(other)
raise "error" unless other.respond_to? :x
or if you want to ensure object passed into the + function has to be of class A, you can add this instead:
raise "error" unless other.is_a? A
J
Instance Variable
Java and C++ programmers are used to declaring their variables in a class, and they think they should do the same in Ruby. WRONG!
For example:
class Animal
@age = 0
@name = ""
def initialize(age, name)
@age = age
@name = name
end
end
In this example, two sets of @age, @name are created. When the initialize method is called, self holds an instance of the Animal class. But the code outside of that function are executed as part of the definition of the Animal class. When @age and @name are executed, it refers to the Animal class, not the object instance. Hence @age, @name inside the initialize function are different from the @age, @name on the outside.
J
For example:
class Animal
@age = 0
@name = ""
def initialize(age, name)
@age = age
@name = name
end
end
In this example, two sets of @age, @name are created. When the initialize method is called, self holds an instance of the Animal class. But the code outside of that function are executed as part of the definition of the Animal class. When @age and @name are executed, it refers to the Animal class, not the object instance. Hence @age, @name inside the initialize function are different from the @age, @name on the outside.
J
Sunday, September 21, 2008
Variable Parameters
Sometimes we want a method that can take any number of parameters.
One way to do it is to pass in a hash, but this can be annoying. Another method is to put an * before the method's parameter. Within the body of the method, list will be treated as an array with 0 or more elements.
For example:
def average(*list)
x = 0
list.each {|l| x+= l}
l/list.size
end
irb>average 1,2,3,4,5,6,7,8,9
=> 5
J
One way to do it is to pass in a hash, but this can be annoying. Another method is to put an * before the method's parameter. Within the body of the method, list will be treated as an array with 0 or more elements.
For example:
def average(*list)
x = 0
list.each {|l| x+= l}
l/list.size
end
irb>average 1,2,3,4,5,6,7,8,9
=> 5
J
Copying Objects
When you use =, clone, or dup to copy an object, only the object reference is copied,
not the referenced object itself (Shallow Copy).
In order to do a deep object copy, we can use the marshaling trick by dumping and
loading the object.
For example:
def deepcopy(something)
Marshal.load(Marshal.dump(something))
end
irb>b = "abcd"
=> "abcd"
irb>a = b
=> "abcd"
irb>a.upcase!
=>"ABCD"
irb>b
=>"ABCD" # see how b changes too
irb>b = deepcopy(a)
=>"ABCD"
irb>b.downcase!
=>"abcd"
irb>a
=>"ABCD" # a stayed the same this time
J
not the referenced object itself (Shallow Copy).
In order to do a deep object copy, we can use the marshaling trick by dumping and
loading the object.
For example:
def deepcopy(something)
Marshal.load(Marshal.dump(something))
end
irb>b = "abcd"
=> "abcd"
irb>a = b
=> "abcd"
irb>a.upcase!
=>"ABCD"
irb>b
=>"ABCD" # see how b changes too
irb>b = deepcopy(a)
=>"ABCD"
irb>b.downcase!
=>"abcd"
irb>a
=>"ABCD" # a stayed the same this time
J
Saturday, September 20, 2008
More on enumerable
In ruby, I use .each alot to visit every elements in the array.
Did you know there's a .step(x) function that allows you to visit
every x th element in the array?
For example:
r = 0..3
r.each {|l| prints l.to_s + ' ' } # Prints 0 1 2 3
r.step(2) {|l| prints l.to_s + ' '} # Prints 0 2
J
Did you know there's a .step(x) function that allows you to visit
every x th element in the array?
For example:
r = 0..3
r.each {|l| prints l.to_s + ' ' } # Prints 0 1 2 3
r.step(2) {|l| prints l.to_s + ' '} # Prints 0 2
J
Thousands Seperator
In ruby, underscore can be inserted into integer literals as thousands separator.
For example:
1_000 will be interpreted as 1000
1_000 + 1_000 will equal 2000
1_000_000_000 will be interpreted as 1 billion
the same technique works for float number as well
For example:
1_000.1 will be interpreted as 1000.1
J
For example:
1_000 will be interpreted as 1000
1_000 + 1_000 will equal 2000
1_000_000_000 will be interpreted as 1 billion
the same technique works for float number as well
For example:
1_000.1 will be interpreted as 1000.1
J
Friday, September 19, 2008
Prototype: $A is not defined
Ever get this annoying error? Well... I do. Odd thing is, everything still works like a charm. So what's happening.
Unfortunately, no one seems to really know! I did some digging and found this bug. If you go through the comments, Prototype has some problems when loading/unloading a page on Firefox 2. Or maybe it's Firebug. People can't seem to entirely agree, and the bug has been reopened several times.
However, if you want a patch and forget about finding out what the problem really is, check out this fix.
I've used it and forgot about it now. Would be nice to know why though...
W
Unfortunately, no one seems to really know! I did some digging and found this bug. If you go through the comments, Prototype has some problems when loading/unloading a page on Firefox 2. Or maybe it's Firebug. People can't seem to entirely agree, and the bug has been reopened several times.
However, if you want a patch and forget about finding out what the problem really is, check out this fix.
I've used it and forgot about it now. Would be nice to know why though...
W
Thursday, September 18, 2008
Dropbox
Recently, there has been a lot of buzz around Dropbox. It is now open to beta testing, and many people say it's awesome.
In short, Dropbox can be thought of as storage that you can access from anywhere you have an internet connection. It'll automatically sync your local and remote files, and also work on PCs, Macs, and *nix machines.
For those of you that move around a lot and need your files reliably without the hassle, check out Dropbox.
W
In short, Dropbox can be thought of as storage that you can access from anywhere you have an internet connection. It'll automatically sync your local and remote files, and also work on PCs, Macs, and *nix machines.
For those of you that move around a lot and need your files reliably without the hassle, check out Dropbox.
W
Wednesday, September 17, 2008
Database Visualization
Keeping documentation up-to-date is always a pain in the ass. I was recently working on updating our database diagrams and thought that there may be a way to automate the process.
I found 2 solutions:
1. XMI
2. RailRoad
For solution (1), it worked, but I had to tweak it slightly. Because we are using PostgreSQL, I had a problem when UmlDumper tried to execute current_database for the adapter. This works fine for the MySQL adapter, but no such function exists for the PostgreSQL adapter. I quickly hacked it and just replaced it with a general name for our database, as we didn't have to be dead-on here.
I was quite disappointed when Dia did not know how to open up the XMI file. So, searching around, I found a program called Umbrello. It works great. Unfortunately, I had all my UML classes, but no diagram! I had to drag and drop each one individually (I couldn't figure out how to drag them all at the same time T.T). I then manually added in all the lines and made it pretty. Not too bad, but it was partly automated and partly manual.
For solution (2), it worked great. I used a rake task to generate the svg files. I had several issues with this, which was the fact that RailRoad is used to diagram models in RoR, not the database. Hence, I ended up with a lot of relations that didn't exist in the database. This meant TONS of lines. The lines are also quite hard to follow as they constantly overlap and cross each other.
2 major issues I had was that there is a 1-to-1 relationship (for efficiency purposes). However, the diagram did not reflect this. For example, we have class A and B that are in a 1-to-1 relationship. A will have has_many relationships and so will B. However, the diagram showed that all of B's has_many relationships were related to A, not B. I couldn't figure out why.
The other issue was a logged bug. If the model ends in an 's', the diagram gets messed up. The diagram will automatically drop the trailing 's'. This created incorrect relationships.
For these 2 major issues, I was unable to use solution (2) in the end. However, if more improvements are made, I may give it another chance as the whole process was completely automated. If your interested, it also does Controller diagrams.
If anyone else has a better way of producing automated diagrams of their database or models, give me a shout. I'd love to hear other solutions.
W
I found 2 solutions:
1. XMI
2. RailRoad
For solution (1), it worked, but I had to tweak it slightly. Because we are using PostgreSQL, I had a problem when UmlDumper tried to execute current_database for the adapter. This works fine for the MySQL adapter, but no such function exists for the PostgreSQL adapter. I quickly hacked it and just replaced it with a general name for our database, as we didn't have to be dead-on here.
I was quite disappointed when Dia did not know how to open up the XMI file. So, searching around, I found a program called Umbrello. It works great. Unfortunately, I had all my UML classes, but no diagram! I had to drag and drop each one individually (I couldn't figure out how to drag them all at the same time T.T). I then manually added in all the lines and made it pretty. Not too bad, but it was partly automated and partly manual.
For solution (2), it worked great. I used a rake task to generate the svg files. I had several issues with this, which was the fact that RailRoad is used to diagram models in RoR, not the database. Hence, I ended up with a lot of relations that didn't exist in the database. This meant TONS of lines. The lines are also quite hard to follow as they constantly overlap and cross each other.
2 major issues I had was that there is a 1-to-1 relationship (for efficiency purposes). However, the diagram did not reflect this. For example, we have class A and B that are in a 1-to-1 relationship. A will have has_many relationships and so will B. However, the diagram showed that all of B's has_many relationships were related to A, not B. I couldn't figure out why.
The other issue was a logged bug. If the model ends in an 's', the diagram gets messed up. The diagram will automatically drop the trailing 's'. This created incorrect relationships.
For these 2 major issues, I was unable to use solution (2) in the end. However, if more improvements are made, I may give it another chance as the whole process was completely automated. If your interested, it also does Controller diagrams.
If anyone else has a better way of producing automated diagrams of their database or models, give me a shout. I'd love to hear other solutions.
W
Labels:
ActiveRecord,
Controllers,
Database,
Solutions,
W
Monday, September 15, 2008
Google: AdWords Algorithm
Sorry, this isn't a post about Google's algorithm :P
But, there is news that they're planning to modify it! That's big news to people using AdWords. Go and check it out.
Quick summary:
- dynamic calculations of Quality Score at search time
- keywords are no longer labeled as "inactive for search"
- no more "minimum bids"... in comes "first page bid estimates"
In other words, Google wants more money ;)
W
But, there is news that they're planning to modify it! That's big news to people using AdWords. Go and check it out.
Quick summary:
- dynamic calculations of Quality Score at search time
- keywords are no longer labeled as "inactive for search"
- no more "minimum bids"... in comes "first page bid estimates"
In other words, Google wants more money ;)
W
Sunday, September 14, 2008
JavaScript Heaven
I stumbled across this amazing page of JavaScript tools. Enjoy!
http://www.smashingmagazine.com/2008/09/11/75-really-useful-javascript-techniques/
W
http://www.smashingmagazine.com/2008/09/11/75-really-useful-javascript-techniques/
W
Saturday, September 13, 2008
Y Combinator
Y Combinator is a venture firm that specializes in funding startups in their early stages. I recently discovered their news section, which, as a technical person, I find very interesting. It is a Digg type site that gives links to interesting articles. Every so often, I will also see RoR articles on there. Check it out:
http://news.ycombinator.com/
W
http://news.ycombinator.com/
W
Friday, September 12, 2008
Ubuntu: Volume Problems
Recently, my audio has been much softer than it has been when I first installed Ubuntu. Even if I turn my volume up completely, the audio was only at a normal volume. I found this odd because before, when I turned it up, it would blast my ears off.
I managed to find out why! If you go to your Volume Control, Edit > Preferences, and select PCM. Then turn the PCM volume up to the desired level. Mine, for some reason, was set at a very low volume.
I'm not quite sure what happened, as I never played with my settings. My only guess is that some particular update fooled with the settings.
W
I managed to find out why! If you go to your Volume Control, Edit > Preferences, and select PCM. Then turn the PCM volume up to the desired level. Mine, for some reason, was set at a very low volume.
I'm not quite sure what happened, as I never played with my settings. My only guess is that some particular update fooled with the settings.
W
Tuesday, September 9, 2008
BackgrounDrb.destroy
So we've been noticing some pretty odd things with BackgrounDrb lately. In spite of our previous fixes to BackgrounDrb, we've decided to give up on it. Why? Simply put: It's not working properly.
We've been checking the logs recently, and we've noticed way too many calls to our scheduled tasks. On the odd days, we'll get 3 or 4 extra calls when only 1 was scheduled. I don't know how to explain this, nor do I wish to find out, because frankly, I'm fed up with this.
I admit, it really was my fault for trying to use an overly complicated program to run something very simple. KISS - I know. I'm kicking myself in the ass for this now! Anyways, simple solution: cron. It's the most basic of basic schedulers. You can't go wrong here.
Luckily, all our functions were encapsulated in the models, so the logic didn't need to be changed. We ripped out the stuff in the BackgrounDrb worker and placed them in a rake file. We then called the rake tasks from the cron.
Very simple. Very clean.
Bye Bye BackgrounDrb!
W
We've been checking the logs recently, and we've noticed way too many calls to our scheduled tasks. On the odd days, we'll get 3 or 4 extra calls when only 1 was scheduled. I don't know how to explain this, nor do I wish to find out, because frankly, I'm fed up with this.
I admit, it really was my fault for trying to use an overly complicated program to run something very simple. KISS - I know. I'm kicking myself in the ass for this now! Anyways, simple solution: cron. It's the most basic of basic schedulers. You can't go wrong here.
Luckily, all our functions were encapsulated in the models, so the logic didn't need to be changed. We ripped out the stuff in the BackgrounDrb worker and placed them in a rake file. We then called the rake tasks from the cron.
Very simple. Very clean.
Bye Bye BackgrounDrb!
W
Tuesday, September 2, 2008
Sitemap
It's nice to have a sitemap that adheres to the Sitemap 0.90 protocol. In rails, this can be automatically generated. Unfortunately, you have to do some work.
I found 2 different ways:
1. using controllers
2. using rake
If your site is small, (1) works really well. It's as dynamic as it can be as the sitemap is generated on the fly. However, every time anyone visits that URL, you end up hitting the database for a fairly large call, memory-wise. If it's just legitimate people accessing it, they will access the URL when they need it, or on a periodic time frame. However, if you encounter malicious users (which there are many out there), they could easily overload your server.
(2) is not as up-to-date, but from my point of view, that's ok, especially if you update the files daily. The solution posted works well, but since out site takes advantage of BackgrounDrb, I thought I would modify it to work with BackgrounDrb instead of rake.
I created some self functions to do the database queries and handle the tasks in the rake. Also, in sitemap.rb, I added the lines:
include ActionController::UrlWriter
default_url_options[:host] = 'www.twoblindfish.com'
This allows you to use named routes and url_for. Now we don't need to hardcode our URLs! Another plus! The rest is pretty straight forward. A few of the tasks were redundant, so I refactored them into multiple functions for reuse.
The only thing really different would be to place your sitemaps in public/system/. so that the sitemaps don't get removed when you do a cap:deploy. This works because the public/system folder is symlinked to shared/system.
Hope this helps those in need of generating sitemaps!
W
I found 2 different ways:
1. using controllers
2. using rake
If your site is small, (1) works really well. It's as dynamic as it can be as the sitemap is generated on the fly. However, every time anyone visits that URL, you end up hitting the database for a fairly large call, memory-wise. If it's just legitimate people accessing it, they will access the URL when they need it, or on a periodic time frame. However, if you encounter malicious users (which there are many out there), they could easily overload your server.
(2) is not as up-to-date, but from my point of view, that's ok, especially if you update the files daily. The solution posted works well, but since out site takes advantage of BackgrounDrb, I thought I would modify it to work with BackgrounDrb instead of rake.
I created some self functions to do the database queries and handle the tasks in the rake. Also, in sitemap.rb, I added the lines:
include ActionController::UrlWriter
default_url_options[:host] = 'www.twoblindfish.com'
This allows you to use named routes and url_for. Now we don't need to hardcode our URLs! Another plus! The rest is pretty straight forward. A few of the tasks were redundant, so I refactored them into multiple functions for reuse.
The only thing really different would be to place your sitemaps in public/system/. so that the sitemaps don't get removed when you do a cap:deploy. This works because the public/system folder is symlinked to shared/system.
Hope this helps those in need of generating sitemaps!
W
Subscribe to:
Posts (Atom)