Donnerstag, 26. Juni 2008

named_scope

in the *.rb models

Class Profile << ActiveRecord::Base
belongs_to: user
belongs_to: team
named_scope :captain, :conditions => { :role => "captain" }
named_scope :liverpool, :include :team, :conditions => { 'teams.name' => 'liverpool' }
end

This allows following:

user.profile.liverpool #-> finds all user profiles that are in the team liverpool
user.profile.captain #-> finds all user profiles that have the role of captain.

Methods, Calls, Blocks, Closures & Lambda

Excellent excellent article!!

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

Dienstag, 24. Juni 2008

STUCK things

Associations.
==========

What i want to do....

current_user.following_users.messages

This should deliver a bunch of messages from all the users that the current user is following (a la twitter).

I can't get it to work for the life of me.

################################Here the migrations.

User

create_table "users", :force => true do |t|
t.column :login, :string
t.column :email, :string
t.column :crypted_password, :string, :limit => 40
t.column :salt, :string, :limit => 40
t.column :created_at, :datetime
t.column :updated_at, :datetime
t.column :remember_token, :string
t.column :remember_token_expires_at, :datetime
t.column :activation_code, :string, :limit => 40
t.column :activated_at, :datetime
end


Message

create_table :messages do |t|
t.string :message
t.integer :user_id
t.integer :movie_id
t.timestamps
end


Following

create_table :followings do |t|
t.integer :follower_user_id
t.integer :following_user_id

t.timestamps
end

#############################Here the Models

User

class User < foreign_key =""> :following_user_id, :class_name => "Following"
has_many :follower_users,:foreign_key => :follower_user_id, :class_name => "Following"
has_many :messages
has_many :messages, :through => :follower_users,:foreign_key => :follower_user_id, :class_name => "Following"
has_many :movies, :through => :messages

Message

class Message < foreign_key =""> :following_user_id, :class_name => "Following"
# has_many :follower_users,:foreign_key => :follower_user_id, :class_name => "Following"
end

Following

class Following < foreign_key =""> :follower_user_id, :class_name => "User" #id of the user that is following
belongs_to :following_user, :foreign_key => :following_user_id, :class_name => "User" #id of the user that is being followed
end


+++++++++++++++++++++ my solution so far

@user=User.find_by_id(params[:user_id])
@following_users=@user.followings.each { |follow| follow.user_id }
@messages=Message.find_all_by_user_id(@following_users)

Refactoring
=========

def get_page_count
results = @doc.search("//td[@class='resultCount']/").first.to_s.gsub(/\./,"")
tmp_array=results.scan(/(\d+)-(\d+).*?(\d+)/)
myarray=tmp_array[0]
@max_pages_in_category = 1
if !myarray.nil?
@max_pages_in_category= (myarray[2].to_i / 12) # total number of items / itmes on a page
if (myarray[2].to_i % 12) != 0 then @max_pages_in_category+=1 end
@total_articles_in_category=myarray[2];
end
end


def render_products
titles = @doc.search("//span[@class='srTitle']/")
titles.each do |title|
print "."
string=title.to_s
string.gsub!(/\(.+?\)/,"")
string.gsub!(/\[.+?\]/,"")
if @data_file!=0 : @data_file.puts @tags+":"+string end
end
end


Montag, 23. Juni 2008

Form_for nested

when using nested controllers where forms in the views need to call a nested controller too:

<% form_for([@user, @movie]) do |f| %>
...
<% end %>


This will call the :controller => :movie with the :action => post with the :user_id => @user.id

Freitag, 20. Juni 2008

Model Relationships - has_many belongs_to

ModelOne
has_many :model_twos
has_many :model_threes, :through :model_two

ModelTwo
belongs_to :model_one
belongs_to :model_three

ModelThree
has_many :model_twos
has_many :model_ones, :through :model_two

Rake Scaffold

ruby script/generate scaffold SingularModelName data_field_name:type -c

The -c adds the file generated to the svn repository.

Auto Complete Related Models

Here is an auto_complete example that works accross 2 related models:

movie
has_many :messages

messages
belongs_to :movie

This went in the messages new view.
============================
<%= text_field_with_auto_complete :movie, :movie_name, {:size => 50}, {:url => formatted_movies_path(:js), :method => :get, :param_name => 'search'} %>

as you cannot use the regular auto_complete_for helper for auto complete across models the text_filed_with_auto_complete needs to have a few more things added to it.

:movie is the model name for the auto complete
:movie_name will contain the input from the user
The first {} contains the options for the input field
The second {} contains the options for the java script

in the first {} the field size is set to 50 with :size=>50
in the second {} the
:url tells the auto complete where to go to get its information to give back to the client. In this case its the path to the index function of the movie controller. (:js) means java script is the format to pass around
:method make rails get information rather then post information (which normally happens with the information from an input field)
:param_name set the name of the params hash key with the information being typed into the field.

This was how the messages controller handled the create
===========================================
def create
@message = Message.new(params[:message])
@message.movie=Movie.find_or_create_by_title(:title=> params[:movie][:movie_name])
@message.save
end


This is what happened on the movie index method
======================================
def index
@movies = Movie.find(:all, :limit => 20, :conditions => ['title LIKE?', "%#{params[:search]}%"])

respond_to do |format|
format.html # index.html.erb
format.js #{ render :html => @movies }
format.xml { render :xml => @movies }
end
end

as you can see in the above the index.js.erb file will be rendered when java script is calling this controller method.

This is what the index.js.erb file looks like
================================

<%= auto_complete_result @movies, :title %>

This is a help method from auto complete which renders back the title value for the objects contained in the @movies instance.

!!!!DONT FORGET to add the java script librarys in the layout.
<%= javascript_include_tag :defaults %>

One last thing: Here is the CSS for the auto_complete to add the CSS being used for model so that the defaults can be overridden.

.auto_complete {
position:absolute;
/*width:250; */
overflow: hidden;
white-space: nowrap;
background-color:white;
border:1px solid #888;
margin:0px;
padding:0px;
color: black;
}

.auto_complete ul {
list-style-type: none;
margin:0px;
padding:0px;
color: black;
}

.auto_complete ul li.selected
{
background-color: #fff; /* #bbf; */
color: black;
}

.auto_complete ul li {
list-style-type: none;
display:block;
margin:0;
padding:2px;
height:16px;
color: black;
}

file upload

This file upload form was made to upload a , delimited text file.


<% form_for(@category_movie, :html => { :multipart => true }) do |f| -%>



<%= file_field_tag :dvd_data %>

<%= submit_tag 'Create' %>

<% end -%>

From file to DB through Controller

This method reads data from an uploaded file in a , delimited file and stores it in the database in the movies, categories and category_movies(join table).

category name 1, category name 2, ...., category name x: movie title

def create

while (line=params[:dvd_data].gets)
title=line.scan(/ROOT:.*/).to_s.gsub(/ROOT:/,"")
categories=line.gsub(/ROOT:.*/,"").scan(/.+?,/)
categories.each do |category|
category.gsub!(/,/,"")
the_category = Category.find_or_create_by_name(:name => category)
the_movie= Movie.find_or_create_by_title(:title => title.to_s)
CategoryMovie.find_or_create_by_category_id_and_movie_id(:category_id =>the_category.id, :movie_id=> the_movie.id)
end
end


respond_to do |format|
flash[:notice] = 'DataBase Updated With DVD titles and Categories'
format.html { redirect_to(category_movies_path) }
format.xml { render :xml => @category_movie, :status => :created, :location => @category_movie }
end
end