Tuesday, December 22, 2009

Basic PayPal

RyanB's Railscasts provided the perfect example to adding PayPal functionality to your application, http://railscasts.com/episodes/141-paypal-basics.

But what if let say you don't wanna do a cart system but instead you want the site to take you directly to the payment section in one click. With that of course, you can't have the user selecting items into the cart but that would do if you are charging all users the same price for the same item.

In the view, we will need a link_to taking us to the payment site on PayPal. We can also use a form to have it sent as a POST method if we are concern about the details in the url.


Based on RyanB's tutorial, we will need a sandbox account to play with this kinda stuff before firing up the real deal.

models/user.rb

def paypal_url(return_url)
values = {
:business => 'sell_1261499871_biz@live.com',
:cmd => '_xclick',
:return => return_url,
:invoice => id
}
values.merge!({
"amount" => 500,
"item_name" => "Registration"
})
"https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query
end


So now when we go ahead and click the "Pay Up Now!" link, we will be redirected to the PayPal site where we are gonna pay for a registration fee of $500...

You may like to refer to the documentation and HTML variables for more info and features.

Tuesday, December 8, 2009

Fooling Around With Sessions

A very trivial try,


def session_string
if session[:storage].nil?
session[:storage] = "Hi! i reside in the session storage."
else
session[:storage]
end

This action checks whether the session[:storage] is nil? If it is, then just put a string into it. If it isn't then the action will just return the session.


puts session[:storage]

It will display the string stored in the session.

A lil part i picked, from the Agile Development Rails book,


def find_cart
unless(session[:cart])
session[:cart] = Cart.new
end
session[:cart]
end


This action will check if a session[:cart] is nil or contains a cart. If it doesn't then create a new Cart object and store it into the session. If there is, then it will just return the session[:cart] which contains a former Cart object in it.

Session is stored in a cookie by default in Rails. So each browser will have its own session storage and will interact differently between different clients.

Thursday, September 3, 2009

JQuery on Rails

I am starting to test out JQuery on Rails and see if i can reproduce the same result of what i did back then with the Rails bundled Prototype helpers.

in rjs, (js.rjs)

page.replace_html "widget-count-#{@post.id}", :partial => 'widget_count', :locals => {:post => @post}
page.replace "widget-button-#{@post.id}", image_tag('wiggy.png')

in jquery, (js.erb)

$("#widget-count-<%= @post.id %>").replaceWith
('<%= escape_javascript(render(:partial => 'widget_count', :locals => {:post => @post} ))%>');
$("#widget-button-<%= @post.id %>").replaceWith
('<%= image_tag('wiggy.png') %>');


in addition to that, if you are using JQuery, do not forget to import that JQuery javascript file.

However, if you are dealing with ajax request... there is something extra you need to do. Based on RyanB's railscast at http://railscasts.com/episodes/136-jquery,

in application.js

#to request for js format by default instead of html if you have both respond_to |format|

jQuery.ajaxSetup({
'beforeSend' : function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})


#Changing the behavior of the form, note the form id "new_comment" to submit an ajax request

$(document).ready(function(){
$("#new_comment").submit(function(){
$.post($(this).attr("action"), $(this).serialize(), null, "script");
return false
})
})


JQuery.js has to be loaded first before application.js in order to get it work.

Then for the appearance of the comment in an ajax manner,

in rjs, (js.rjs)

if @comment.save
page.insert_html :top,"comments", :partial => 'comment'


in jquery, (js.erb)

<% if @comment.save %>
$("#comments").prepend("<%= escape_javascript(render :partial => 'comment') %>")
<% end %>


Finally if you intend to use JQuery with other Javascript libraries, Prototype for example, bear in mind the need to declare noconflict. http://docs.jquery.com/Using_jQuery_with_Other_Libraries

One of the example to prevent conflict between JQuery and Prototype is by,

Add this right after the libraries are loaded. Perhaps in application.js

jQuery.noConflict();

Then anytime you intend to use JQuery libraries wrap the JQuery codes inside the jQuery(document).ready(function($){ #jquery codes }) as such,

jQuery(document).ready(function($){
<% if @comment.save %>
$("#comments").prepend("<%= escape_javascript(render :partial => 'comment') %>");
<% else %>
alert('NO!');
<% end %>
})


The $(element) codes without wrapping into jQuery will be treated as Prototype and the score is settled.

Wednesday, August 5, 2009

Ruby Setter and Getter Methods

class Person

def initialize(name,age)

@name = name

@age = age

end

def name=(name)

@name = name

end

def age=(age)

@age = age

end

def name

@name

end

def age

@age

end

can be written with
class Person

attr_accessor :name, :age

def initialize(name,age)

@name = name

@age = age

end

By using attr_accessor, you will automatically get the setter and getter method. Take note that there are some hashes following it.

If you only want the setter method, go for attr_writer, while the getter method, go for attr_reader.

While it is also possible to use attr :name to get attr_reader, and attr :name, true to get the same effect as attr_accessor, but it looks less readable than the previous ones.

Using setter, the set method becomes similar to variable assignment when it's actually a method call.

Tuesday, July 7, 2009

Rails 2.3 Model Nested Form

http://railscasts.com/episodes/73-complex-forms-part-1

http://railscasts.com/episodes/74-complex-forms-part-2

http://railscasts.com/episodes/75-complex-forms-part-3

Ryan made a great introduction about having a form dealing with multiple models. Yet in Rails 2.3 due to popular demand, it is already bundled with this feature.

http://weblog.rubyonrails.org/2009/1/26/nested-model-forms

http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

http://stackoverflow.com/questions/818460/problems-with-nested-form-fields-showing-up

First of all, the model has to know about the nested attributes. With that the course can access the sections_attributes.
class Course < ActiveRecord::Base
has_many :sections

accepts_nested_attributes_for :sections

end

Then for the view at new.html.erb
<% form_for @course do |course_form| %>

<%= course_form.label :title %>
<%= course_form.text_field :title %>

<% course_form.fields_for :sections do |section_form| %>

<%= section_form.label :sec %>
<%= section_form.text_field :sec %>

<% end %>

<%= submit_tag %>
<% end %>

In the controller, there is a need to add @course.sections.build at the new action in order to populate the form and create the section together with the course in a hash.
def new
@course = Course.new
@course.sections.build
end

But, wait there is more... you might wanna add more sections dynamically... and i found a tutorial that just do that

http://railsforum.com/viewtopic.php?id=28447

Thursday, July 2, 2009

Sending Email on Rails via Gmail

If you need to send an email via Gmail on a Rails application ( and if you are running Rails >= 2.2.1 with Ruby 1.8.6 )

1) Register a gmail account

2) Install the ActionMailer_tls gem from http://github.com/openrain/action_mailer_tls/tree/master

3) Follow the instruction on the readme of the Gem,

  • To install the gem (the preferred way):1. `sudo gem install openrain-action_mailer_tls -s http://gems.github.com`
    2. `./script/generate action_mailer_tls`
    3. Copy RAILS_ROOT/config/smtp_gmail.yml.sample to RAILS_ROOT/config/smtp_gmail.yml
    4. Update the configuration file with your settings by keying in your gmail username and password on smtp_gmail.yml


Make sure the username includes @gmail.com in the smtp_gmail.yml file
:user_name: testing123@gmail.com
:password: thisisatestpassword

And you are good to go, in order to test if the mail is actually sent, follow the testing instruction in the README.

Thanks to http://www.justinball.com/2009/06/25/sending-email-with-ruby-on-rails-2-3-2-and-gmail/

Friday, June 12, 2009

Vote_fu Sort Order by Vote_for

@stories = Story.tally( :conditions => {:votes => {:vote => true}}).paginate :page => params[:page], :per_page => 8

After several attempts, i tried putting this condition, and it seems as if the data are sorted according to the number of vote_for it...

It has already included the association table in the plugin perhaps.

Databse Query

I was having some problem with database querying... googled around, and maybe i should remember to come back to this if i were to encounter them again

http://guides.rubyonrails.org/active_record_querying.html
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
http://ryandaigle.com/articles/2008/7/7/what-s-new-in-edge-rails-easy-join-table-conditions

Tuesday, June 9, 2009

Pagination

Pagination is used tomanage the population data in a single view such as having..


1 | 2 | 3 | next...


The complete how-tos are at http://wiki.rubyonrails.org/howtos/pagination or page 521 Pragmatic Agile Web Development with Rails 3rd Edition



.paginate is similar to .find but it's able to support the argument for :page => params[:page]



It is also possible to chain the pagination. Like using vote_fu's tally,


@users = User.tally().paginate :page => params[:page], :per_page => 8, :order => "name"



In the view, to have the 1,2,3,next etc...


this code needs to be added <%= will_paginate @models %>

Friday, May 29, 2009

Adding Times Ago

We will have to make use of the timestamp created_at data that was automatically assigned when the data is created.

In the view of html.erb.
<%= time_ago_in_words(m.created_at) %> ago

Customize Root

To display your own index page in http://localhost:3xxx.

In config/routes.rb for instance,
map.root :controller => 'posts'

And be sure to delete the index page in public/index.html

Monday, May 25, 2009

Clean URL Namings

Make sure the application applies the RESTful method

route.rb
ActionController::Routing::Routes.draw do |map|

map.resources :posts

end

apps/model/Post.rb
class Post < ActiveRecord::Base
validates_presence_of :name, :crews

def to_param
"#{id}-#{name.gsub(/\s/,'_').downcase.gsub(/\?/,'')}"}"
end

end

"#{id}-#{name.gsub(/<Regular Expressions>,'<Replace using gsub>').downcase}"

http://e-texteditor.com/blog/2007/regular_expressions_tutorial for more information regarding Regular Expressions.

It is crucial to deal with the punctuation to avoid routing errors.

In the View
<%= link_to post.title, post_path(post) %> // With Routing

<%= link_to post.title, :action => 'show', :id => 'post' %> // Without Routing

I referred to

http://railscasts.com/episodes/63-model-name-in-url

http://blog.imperialdune.com/2007/2/13/pretty-urls-with-restful-rails

http://www.matthias-georgi.de/2007/4/pretty-restful-urls-in-rails