I came across a blog post that talks how to maintain a reference to javascript popup window while the parent window has been navigated away. This scenario doesn't want to reload the child popup window. I just quoted out from
1 Pixel Out. There is a really nick trick.
In the main window:
var popupWin = null;
function openPopup() {
var url = "popup.htm";
popupWin = open( "", "popupWin", "width=500,height=400" );
if( !popupWin || popupWin.closed || !popupWin.doSomething ) {
popupWin = window.open( url, "popupWin", "width=500,height=400" );
} else {
popupWin.focus();
}
}
function doSomething() {
openPopup();
popupWin.doSomething();
}
In the popup:
self.focus();
function doSomething() {
alert("I'm doing something");
}
http://www.bennadel.com/blog/89-Maintaining-Javascript-Pop-Up-Window-Communication-Across-Window-Opener-Page-Loads.htmhttp://www.1pixelout.net/2005/04/19/cross-window-javascript-communication/http://www.1pixelout.net/2006/12/15/cross-window-javascript-communication-20/http://www.1pixelout.net/wp-content/downloads/popups20.zip
It reminds me about uploading via iframe that I did a year ago when my colleague asked me to help with login openid in a popup window. It's a similar story with this problem. Actually, login with openid could not place in a iframe because you could the code that prevents this.
<script type="text/javascript">if(top == self) { document.write(""); } else { top.location.href = "http://www.yahoo.com"; }</script>
Now, let's see a quick summary on this basic communication.
Communication from parent to child window, you need to a reference of the child window so that can call any function in the child window.
// Create a new popup window
var popupWin = window.open(url, "popupWin");
// To call functions defined in the popup:
popupWin.doSomething();
Communication from child to parent window, you need to use this way:
window.opener.doSomethingOnParent();
Here is the problem, the parent window needs to know when the uploading (in iframe) or logging in (in popup window) is done. The only way that the parent window can notified by the child window after finish processing. Usually, for uploading and logging in with openid, the action in your controller would render a view back. The trick is here on the onload of the body, you could notify the parent window.
def login
@status = "something"
end
#view
<html><head></head>
<body onload="window.opener.handleOpenIDResponse('" + @status + "');window.close();">
</body>
</html>
That would solve the problem, and you could send any information back through your view.
Well, I had been quite confusing about these two topics before I read some rails books. These are just different ways to do many to many relationships in ActiveRecord.
has_and_belongs_to_many (habtm)habtm is the very old way since rails 1.2. It creates a link between associated models through an intermediate join table.
class CreateProjectsProgrammers < ActiveRecord::Migration
def self.up
create_table :projects_programmers, :id => false do |t|
t.column :project_id, :integer, :null => false
t.column :programmer_id, :integer, :null => false
end
end
def self.down
drop_table :projects_programmers
end
end
class Programmer < ActiveRecord::Base
has_and_belongs_to_many :projects # foreign keys in the join table
end
class Project < ActiveRecord::Base
has_and_belongs_to_many :programmers # foreign keys in the join table
end
Note that an id primary key is not needed in the join table and there is no join model, only join table. Here we will face a problem when we want to add extra columns on the join table. If it is in rails 1.2, we would have used
push_with_attributes to do this. However,
push_with_attributes has been deprecated in favor of a far more powerful technique, where regular Active Record models are used as join tables (remember that with habtm, the join table is not an Active Record object).
To conclude, habtm is a simple way to do a many-to-many relationship using a join table when the join table doesn't have extra columns. You will need to upgrade the relationship to use
has_many :through once you need to add additional columns.
has_many :throughRecords in the join table of habtm implementation has no independent existence. Later, we will find it very soon that the join table has a life of its own and should have a model when we add extra columns on that join table. Let's talk about relationship between article, user, and the join model is reading.
When a user reads an article, we can record the fact.
class Article < ActiveRecord::Base
has_many :readings
end
class User < ActiveRecord::Base
has_many :readings
end
class Reading < ActiveRecord::Base
belongs_to :article
belongs_to :user
end
reading = Reading.new
reading.rating = params[:rating]
reading.read_at = Time.now
reading.article = current_article
reading.user = session[:user]
reading.save
Here we lost what habtm solved. We could not ask a user which articles that they has read and vice versa. To solve this, use :through options inside has_many.
class Article < ActiveRecord::Base
has_many :readings
has_many :users, :through => :readings
end
class Reading < ActiveRecord::Base
belongs_to :article
belongs_to :user
end
class User < ActiveRecord::Base
has_many :readings
has_many :articles, :through => :readings
end
Now, you could do query both direction:
readers = an_article.users
articles = a_reader.articles
Unlike a normal has_many, ActiveRecord won’t let us add an object to the the has_many :through association if both ends of the relationship are unsaved records. The create method saves the record before adding it, so it does work as expected, provided the parent object isn’t unsaved itself. To add extra attributes:
user.readings.create(:read_at => Time.now,
:rating => params[:rating],
:article => Article.new)
Choosing which way to build a many-to-many relationship is not always simple. If you need to work with the relationship model as its own entity, use has_many :through. Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.
http://blog.hasmanythrough.com/2006/4/20/many-to-many-dance-offhttp://blog.hasmanythrough.com/2006/4/17/join-models-not-proxy-collections
Consider the following scenario, you want to store information about current user. After successful login, you might do this.
user = User.authenticate(params[:user_name], params[:password])
if user
session[:current_user] = user.attributes
else
flash[:notice] = "Email and password do not match."
redirect_to :controller => "login"
end
Everything would work as you expected except when you try to change the structure of your session. This would make sessions of online users invalid while they are using your web application. For example, they will feel annoying while they are adding items to their wish lists. Another problem is that you want to make that session invalid after you delete that user account, for example. That won't work because you stored the entire record in his session. The only way to do is to add before_filter in application controller to check the existence of the current user. That would make another job to do it.
The best practice is store only simple data in the session: strings, numbers, and so on. Keep your application objects in the database, and then reference them using their primary keys from the session data.
class ApplicationController < ActionController::Base
before_filter :get_current_user
private
def get_current_user
@current_user = User.find_by_id(session[:user_id])
end
end
Here you can access @current_user everywhere in your application and solve many issues during development.
I came across to write a custom rake script for my rails application. Because my application is rich client side application and doesn't use id for any of my models. Instead, it used UUID as a primary key. I got some problems while changing this, and one of them is rails rake commands such as rake
db:test:prepare, rake test:functionals, .... For my application, these two commands didn't work really well since it makes my test database messed with autonumber id of all tables. Here, my rake script to load to my test database. Pay attention to mysql command, in this case, I need to run several commands inside mysql command.
task :load_test_db do
#load data to development
Rake::Task["db:fixtures:load"].invoke
#clone development to test
Rake::Task["db:test:clone_structure"].invoke
#pull data from development
sh "mysqldump > test.sql development_ncdd_templates -u root"
sh "mysql -u root << EOF
use test_ncdd_templates;
source test.sql;
exit
EOF"
end
If you want to run bash command, take this as an example. I'm not a expert of shell script, but it works for me anyway.
sh "#!/bin/bash
cd lib
ruby to_yml.rb
cd .."
Here are some excellent sources:
http://www.railsenvy.com/2007/6/11/ruby-on-rails-rake-tutorialhttp://railscasts.com/episodes/66-custom-rake-tasks
I conducted a training to some developers in my office about one full day, yesterday. It is quite exhausted anyway, but everyone seems understand really well. This slide covers many advanced features of JavaScript: Function, Object, Closure,.... Some other points I have pointed out in this slide are about how to make private variable, public variable, static variable, privileged variable and how to do inheritance. I took about 20 different sources as my references and three famous authors. It took me two weeks, at every weekend, to finish this slide.
I have just reviewed JavaScript Design Patterns, and I think it is good to mention this.
It is possible to do a mixin class in JavaScript as in Ruby. This is another way to make our code reuse without inheritance. Consider you have a function, and you wish to use in many classes. In practice, you create a class that contains your general-purpose methods, and then use it to augment other classes. Class with these general-purpose methods is called Mixin class. It is generally not instantiated or called directly, instead it exists to provide methods to other classes.
var Mixin = function() {};
Mixin.prototype = {
serialize: function() {
var output = [];
for(key in this) {
output.push(key + ': ' + this[key]);
}
return output.join(', ');
}
};
This sort of method could potentially be useful in many different types of classes, but it doesn’t make sense to have each of these classes inherit from Mixin. Similarly, duplicating the code in each class doesn’t make much sense either. The best approach is to use the augment function to add this method to each class that needs it:
augment(Author, Mixin);
var author = new Author('Ross Harmes', ['JavaScript Design Patterns']);
var serializedString = author.serialize();
This can be thought of as a way to implement multiple inheritance in JavaScript.
/* Augment function. */
function augment(receivingClass, givingClass) {
for(methodName in givingClass.prototype) {
if(!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
A more robust augment allows copying one or two of them over to another class.
/* Augment function, improved. */
function augment(receivingClass, givingClass) {
if(arguments[2]) { // Only give certain methods.
for(var i = 2, len = arguments.length; i < len; i++) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
}
else { // Give all methods.
for(methodName in givingClass.prototype) {
if(!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
}
You can now write augment(Author, Mixin, 'serialize'); to only augment Author with the single serialize method.
In other times, you don't have to need this augment function in order to do Mixins. You could do this by using apply or call method inside constructor function.
var Author = function(name, books) {
this.name = name || "";
this.books = books || [];
Mixin.apply(this);
};
Often it makes more sense to augment a class with a few methods than it does to make
one class inherit from another. This is a lightweight way to prevent code duplication. Unfortunately, there aren’t many situations where it can be used. Only methods general enough to be used in very dissimilar classes make good candidates for sharing (if the classes aren’t that dissimilar, normal inheritance is often a better choice).
While it is possible to emulate classical inheritance like Java or C#, it is clear that we do prototypal inheritance by taking advantages of prototype lookup chains. Each has its own advantages and disadvantages.
The classical approach to creating an object is to (a) define the structure of the object, using
a class declaration, and (b) instantiate that class to create a new object. Objects created in this
manner have their own copies of all instance attributes, plus a link to the single copy of each
of the instance methods.
In prototypal inheritance, instead of defining the structure through a class, you simply
create an object. This object then gets reused by new objects, thanks to the way that prototype
chain lookups work. It is called the prototype object because it provides a prototype for what the other objects should look like.
Instead of using a constructor function named Person to define the class structure, Person
is now an object literal. It is the prototype object for any other Person-like objects that you want to create. Define all attributes and methods you want these objects to have, and give them
default values.
/* Person Prototype Object. */
var Person = {
name: 'default name',
getName: function() {
return this.name;
}
};
var reader = clone(Person);
alert(reader.getName()); // This will output 'default name'.
reader.name = 'John Smith';
alert(reader.getName()); // This will now output 'John Smith'.
To create a new Person-like object, use the clone function. This provides an empty object with
the prototype attribute set to the prototype object. This means that if any method or attribute
lookup on this object fails, that lookup will instead look to the prototype object.
To create Author, you make a clone.
/* Author Prototype Object. */
var Author = clone(Person);
Author.books = []; // Default value.
Author.getBooks = function() {
return this.books;
}
var author0 = clone(Author);
author0.name = 'Dustin Diaz';
author0.books = ['JavaScript Design Patterns'];
var author1 = clone(Author);
author1.name = 'Ross Harmes';
author1.books = ['JavaScript Design Patterns'];
Here is the clone function. First the clone function creates a new and empty function, F. It then sets the prototype attribute of F to the prototype object. Lastly, the function creates a new object by calling the new operator on F. The cloned object that is returned is completely empty, except for the prototype attribute, which is (indirectly) pointing to the prototype object, by way of the F object.
/* Clone function. */
function clone(object) {
function F() {}
F.prototype = object;
return new F;
}
In classical inheritance, each instance of Author has its own copy of the books array. You could add to it by writing author1.books.push('New Book Title'). That is not initially possible with the object you created using prototypal inheritance because of the way prototype chaining works. A clone is not a fully independent copy of its prototype object; it is a new empty object with its prototype attribute set to the prototype object. When it is just created, author1.name is actually a link back to the primitive Person.name. When you write to author1.name, you are defining a new attribute directly on the author1 object.
var authorClone = clone(Author);
alert(authorClone.name); // Linked to the primative Person.name, which is the
// string 'default name'.
authorClone.name = 'new name'; // A new primative is created and added to the
// authorClone object itself.
alert(authorClone.name); // Now linked to the primative authorClone.name, which
// is the string 'new name'.
authorClone.books.push('new book'); // authorClone.books is linked to the array
// Author.books. We just modified the
// prototype object's default value, and all
// other objects that link to it will now
// have a new default value there.
authorClone.books = []; // A new array is created and added to the authorClone
// object itself.
authorClone.books.push('new book'); // We are now modifying that new array.
Classical inheritance is well understood, both in JavaScript and the programmer commu-
nity in general. Almost all object-oriented code written in JavaScript uses this paradigm. If you
are creating an API for widespread use, or if there is the possibility that other programmers not
familiar with prototypal inheritance will be working on your code, it is best to go with classical.
JavaScript is the only popular, widely used language that uses prototypal inheritance, so odds
are most people will never have used it before. It can also be confusing to have an object with
links back to its prototype object. Programmers who don’t fully understand prototypal inheri-
tance will think of this as some sort of reverse inheritance, where the parent inherits from its
children. Even though this isn’t the case, it can still be a very confusing topic. But since this
form of classical inheritance is only imitating true class-based inheritance, advanced JavaScript
programmers need to understand how prototypal inheritance truly works at some point any-
way. Some would argue that hiding this fact does more harm than good.
Another powerful feature of ActiveRecord is dirty objects. This module tracks unsaved attribute changes. This feature is available probably since
March, 2008. See examples below:
A newly instantiated object is unchanged:
person = Person.find_by_name('uncle bob')
person.changed? # => false
Change the name:
person.name = 'Bob'
person.changed? # => true
person.name_changed? # => true
person.name_was # => 'uncle bob'
person.name_change # => ['uncle bob', 'Bob']
person.name = 'Bill'
person.name_change # => ['uncle bob', 'Bill']
Save the changes:
person.save
person.changed? # => false
person.name_changed? # => false
Assigning the same value leaves the attribute unchanged:
person.name = 'Bill'
person.name_changed? # => false
person.name_change # => nil
Which attributes have changed?
person.name = 'bob'
person.changed # => ['name']
person.changes # => { 'name' => ['Bill', 'bob'] }
Before modifying an attribute in-place:
person.name_will_change!
person.name << 'by'
person.name_change # => ['uncle bob', 'uncle bobby']
Last month, I did a presentation to my team about Restful Rails. I just uploaded to
http://www.slideshare.net/cchamnap/rest-in-rails. It might be useful for newbie rails developer.