ActiveRecord named_scope коллизии

среда, 17 марта, 2010
Что будет в цепочке,
BDSM.active_advisor.for_customer(123456)

если


named_scope :active_advisor,
  :joins => 'INNER JOIN listings l ON (l.id = favorite_listings.listing_id)
             INNER JOIN users u ON (u.id = l.user_id)',
  :conditions => ['u.status = ?', User::Status::ACTIVE]

named_scope :for_customer, lambda{|customer_id| {
  :joins => 'INNER JOIN listings l ON (l.id = favorite_listings.listing_id)
             LEFT JOIN customers c ON (c.user_id = l.user_id AND c.customer_id = favorite_listings.user_id)',
  :conditions => "l.user_id = #{customer_id}"}}

а получится кака с alias -ами и extra join

Mysql::Error: Not unique table/alias: 'l':
SELECT `favorite_listings`.* FROM `favorite_listings`
INNER JOIN listings l ON (l.id = favorite_listings.listing_id)
LEFT JOIN customers c ON (c.user_id = l.user_id AND c.customer_id = favorite_listings.user_id)
INNER JOIN listings l ON (l.id = favorite_listings.listing_id)
INNER JOIN users u ON (u.id = l.user_id)
WHERE ((l.user_id = 123456) AND (u.status = 1))

решается начиная с rails 2.2 (патч тут)

:joins с 2+ джойнами заменяем на массив джойнов, и activerecord здесь делает uniq


named_scope :active_advisor,
  :joins => ['INNER JOIN listings l ON (l.id = favorite_listings.listing_id)',
             'INNER JOIN users u ON (u.id = l.user_id)'],
  :conditions => ['u.status = ?', User::Status::ACTIVE]

named_scope :for_customer, lambda{|customer_id| {
  :joins => ['INNER JOIN listings l ON (l.id = favorite_listings.listing_id)',
             'LEFT JOIN customers c ON (c.user_id = l.user_id AND c.customer_id = favorite_listings.user_id)'],
  :conditions => "l.user_id = #{customer_id}"}}

на выходе вменяемый SQL без лишних джойнов

SELECT `favorite_listings`.* FROM `favorite_listings`
INNER JOIN listings l ON (l.id = favorite_listings.listing_id)
LEFT JOIN customers c ON (c.user_id = l.user_id AND c.customer_id = favorite_listings.user_id)
INNER JOIN users u ON (u.id = l.user_id) WHERE ((l.user_id = 123456) AND (u.status = 1))

sitemap

четверг, 5 июня, 2008

Буквально пару дней, как яндекс стал поддерживать sitemap

появился раздел “Файлы Sitemap” в панели вебмастера, где можно добавить путь к этому файлу.

также путь можно указать в robots.txt


User-agent: Yandex
Sitemap: http://sumskyi.com/sitemap.xml

выкладываю маленькую штуку для генерирования этих самых сайтмапов из базы данных MySQL
required: ruby, activerecord (часть ruby on rails, ror)

Это походу и маленькое руководство по использованию activerecord без рельсов

размазано по 3м файлам
- данных для коннекта
- код
- шаблон

шаблон содержит только обязательные параметры формата sitemap.

bin/db.yml:


adapter: mysql
database: sumskyi
username: root
password: ~
host: localhost
encoding: utf8

bin/sitemap.rb:


#!/usr/bin/env ruby

require 'rubygems'
require 'activerecord'
require 'erb'

cur_dir = File.dirname(__FILE__)

template = File.read("#{cur_dir}/sitemap.erb")

dbconfig = YAML::load(File.open("#{cur_dir}/db.yml"))

ActiveRecord::Base.establish_connection(dbconfig)

class Article < ActiveRecord::Base
end

@urls = Article.find(:all, :select => 'id, link, DATE_FORMAT(created_at, "%Y-%m-%d") as cr', :order => "id ASC")

sitemap = ERB.new(template).result(binding)

file =  File.new('../sitemap.xml', 'w+')
file.puts sitemap
file.close

bin/sitemap.erb:


<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><% for url in @urls %>
  <url>
    <loc>http://sumskyi.com/articles/<%= url.link %></loc>
    <lastmod><%= url.cr %></lastmod>
  </url><% end %>
</urlset>