Thursday, February 25, 2010
Using REXML to read small xml files and load into database table
require 'rexml/document'
require 'rubygems'
include REXML
#def import_xml(tag)
file= File.new(RAILS_ROOT + "/file.xml")
doc= Document.new(file.read)
Ingredient.benchmark("Truncating ingredient table and inserting new records") do
#truncate ingredient table
ActiveRecord::Base.connection.execute("TRUNCATE ingredient")
# read table contents
XPath.each( doc, "//INGREDIENT_SUBSTANCES//ING" ){|ingredient|
ingredient_params = {}
#if there are more than one attributes for table then create a hash.
ingredient.children.each do |child|
key = "#{child.name}".to_sym
if key.to_s == "ISID"
@isid_value = child.text
else
ingredient_params[key] = child.text
end
#@desc_value = child.text if key.to_s == "DESC"
end
#create new instance
ingredient = Ingredient.new(ingredient_params)
#set the primary key if mass assigning of primary key is not possible.
ingredient.ISID = @isid_value
#save
ingredient.save
}
end
TRUNCATE All Tables in a Ruby on Rails
TRUNCATE all the tables.
namespace :db do
task :load_config => :rails_env do
require 'active_record'
ActiveRecord::Base.configurations = Rails::Configuration.new.database_configuration
end
desc "Create Sample Data for the application"
task(:truncate => :load_config) do
begin
config = ActiveRecord::Base.configurations[RAILS_ENV]
ActiveRecord::Base.establish_connection
case config["adapter"]
when "mysql"
ActiveRecord::Base.connection.tables.each do |table|
ActiveRecord::Base.connection.execute("TRUNCATE #{table}")
end
when "sqlite", "sqlite3"
ActiveRecord::Base.connection.tables.each do |table|
ActiveRecord::Base.connection.execute("DELETE FROM #{table}")
ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='#{table}'")
end
ActiveRecord::Base.connection.execute("VACUUM")
end
rescue
$stderr.puts "Error while truncating. Make sure you have a valid database.yml file and have created the database tables before running this command. You should be able to run rake db:migrate without an error"
end
end
end
Just create a file named db_truncate.rake in your lib/tasks directory
with this code in it. Save the file and then run rake db:truncate. Your
database now should have no data now. Before you run the task make sure
that you have a valid database.yml file and have created the database
tables before running this command. You should be able to run rake
db:migrate without an error
In case you want to truncate a single table from database all you have to do is
ActiveRecord::Base.connection.execute("TRUNCATE table_name")
Monday, February 15, 2010
Avoid validations on create or update in rails
a.)One solution to avoid validation is by doing something like this
@something = Something.find(params[:id])
@something.column_save = 'your data'
respond_to do |format|
if @something.save(false) #save without validation
b.)Another solution is to write a separate method to validate in the model
please see the example below
validate :validates_uniqueness_of_name
def validates_uniqueness_of_name
return if deleted == true
num_duplicates = self.class.count(:conditions => ["name = ? AND deleted = ?",self.name, false])
if num_duplicates > 0
errors.add(:name, :taken)
end
end
How to delete a many-to-many association with Rails
One solution is to create a new model for the association. It should be the case
if you add attributes to the association (because push_with_attributes is now deprecated).
You can then simply find the association given the ids of your linked object and call destroy.
However, when you don't have any attribute in your liaison, the has_and_belongs_to_many
is nicer to work with. (you don't need a rails model for the liaison.)
Here is a link to the methods has_and_belongs_to_many adds where we can read :
"collection.delete(object, …) - removes one or more objects from the
collection by removing their associations from the join table.
This does not destroy the objects."
Let's assume we dispose of 2 models 'Post' and 'Category' with a N-N association :
class Post < ActiveRecord::Base
has_and_belongs_to_many :categories
end
class Category < ActiveRecord::Base
has_and_belongs_to_many :posts
end
To delete an association (remove a post from a category) you can use this method :
def remove_post_from_category
post = Post.find(params[:post][:id])
category = post.categories.find(params[:category][:id])
if category
post.categories.delete(category)
end
end
This function will destroy the association but won't destroy the category.
You can also removes all the categories from the posts by using :
collection.clear - removes every object from the collection.In our case its
This does not destroy the objects.
post.categories.clear