`

Rails如何给表添加关联ID,并且设置值

 
阅读更多

最近遇到一个这样的问题,现在有这么几张表。user customer identity, 一个user拥有多个customer,一个customer拥有多个identity.

User 表

id integer,
name  varchar(255),
password varchar(255)

 custmer表

id integer,
user_id, integer
name, varchar(255)
phone,varchar(11)

 identify表

id, integer
customer_id, integer
key, varchar(255)
value varchar(255)

 

问题出在这张identity表上。没有存user_id。导致的问题是在找某个user下面所有有某个idetity的customer的时候很费劲。

首先得从customer表中找到user的所有的customer,然后去遍历identity表,找到customer并且是有某个值的customer。如果用rails的activerecord会很麻烦。所以用sql去查询,但是似乎也不是很简单

select * from customer as c , identity as i where(c.user_id = user_id and c.id = i.customer_id and i.key = 'key' and i.value='value')

 这样似乎会简单一些。(为什么没有用表关联,是因为customer这张表是数据基本表,很多表都依赖他,不像让它变得太复杂)看用sql语句会简单一些。但是看起来还是麻烦一些。因为在做反向查询的时候会不断的去连表查。解决办法是给identity表加上一个user_id字段。使用有两种方式。sql和rails migration。先说sql

alert table identity add user_id int(10) not null default 0  ;

update identify as i set user_id=(select user_id from customer as c wherer i.customer_id = c.id)
//update这条sql语句没有试过,当时考虑到它又缺点,没有采用。

刚刚说道这条sql语句有问题,是因为在这里添加了user_id并对旧数据进行了兼容。但是程序中某些地方在存customer的identity的时候并没有提供user_id,所以采用的rails的activityrecord,前半部分和sql一样

add_column :identity, :user_id, :ingeter

Identity.all.each do |item|
    customer = Customer.find_by( {:customer_id => item.customer_id})

    if customer.present? && customer.user_id.present? && item.user_id.nil?
        item.user_id = customer.user_id
        item.save
    end

end

 这部分和上面的sql语句大同小异,只是增加了一些冗余判断,是因为发现在执行sql的时候会报出user_id为空的时候,下面说另外一部分:怎么兼容旧接口。

class Identity 

 before_save: save_default_user_id

 def save_default_user_id
    if self.user_id.nil?
        customer = Customer.find_by( {:id => self.customer_Id} )
        if customer.present? && customer.user_id.present? 
            self.user_id = customer.user_id
       end
    end
 end
end

 这块是rails提供的before_save 他能够在commit之前做一些事,这样就能够保证旧的接口能够继续工作了。

在开发的过程中,开发并不是最复杂的,旧数据的兼容才是重要的,我们要考虑的不简单的只是功能的实现。

 

 

 

 

分享到:
评论
1 楼 心静如止水 2014-09-01  

相关推荐

Global site tag (gtag.js) - Google Analytics