我的Rails项目中有三个模型,分别是用户,游戏,比赛
用户可以在每个游戏上创建许多比赛 所以匹配的表结构就像
table name: game_matches
+----+---------+---------+-------------+------------+
| id | user_id | game_id | match_type | match_name |
+----+---------+---------+-------------+------------+
| 1 | 1 | 1 | practice | |
| 2 | 3 | 2 | challenge | |
| 3 | 1 | 1 | practice | |
| 4 | 3 | 2 | challenge | |
| 5 | 1 | 1 | challenge | |
| 6 | 3 | 2 | practice | |
+----+---------+---------+-------------+------------+
我想根据user_id,game_id和match_type值生成比赛名称
for example match_name should be create like below
+----+---------+---------+-------------+-------------+
| id | user_id | game_id | match_type | match_name |
+----+---------+---------+-------------+-------------+
| 1 | 1 | 1 | practice | Practice 1 |
| 2 | 3 | 2 | challenge | Challenge 1 |
| 3 | 1 | 1 | practice | Practice 2 |
| 4 | 3 | 2 | challenge | Challenge 2 |
| 5 | 1 | 1 | challenge | Challenge 1 |
| 6 | 3 | 2 | practice | Practice 1 |
+----+---------+---------+-------------+-------------+
在创建新记录期间,如何在Rails模型中实现此自动增量值。 任何帮助建议表示赞赏。
谢谢。
答案 0 :(得分:5)
我看到两种解决方法:
触发(假设Postgres):
DROP TRIGGER IF EXISTS trigger_add_match_name ON customers;
DROP FUNCTION IF EXISTS function_add_match_name();
CREATE FUNCTION function_add_match_name()
RETURNS trigger AS $$
BEGIN
NEW.match_name := (
SELECT
CONCAT(game_matches.match_type, ' ', COALESCE(count(*), 0))
FROM game_matches
WHERE game_matches.user_id = NEW.user_id AND game_matches.match_type = NEW.match_type
);
RETURN NEW;
END
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER trigger_add_match_name
BEFORE INSERT ON game_matches
FOR EACH ROW
EXECUTE PROCEDURE function_add_match_name();
请注意,这未经测试。
铁路
class GameMatch
before_create :assign_match_name
private
def assign_match_name
number = GameMatch.where(user_id: user_id, match_type: match_type).count || 0
name = "#{match_type} #{number + 1}"
self.match_name = name
end
end
再次,未经测试。
我希望使用触发器解决方案,因为通过纯SQL插入时可以完全跳过或忽略回调。
我还要添加“ match_number”列而不是全名,然后在“模型”或“装饰器”或“视图助手”(更灵活,I18n)中构造名称,但背后的逻辑保持不变。
答案 1 :(得分:0)
您应该为这两个match_name
和 user
检索最后一个game
,将其拆分,增加计数器,并加一个空格。不幸的是,SQL不提供SPLIT
函数,因此如下所示是一个不错的开始:
SELECT match_name
FROM match_name
WHERE user_id = 3
AND game_id = 2
ORDER BY id DESC
LIMIT 1
实际上,我最好创建类型为match_number
的{{1}}列,以按类型保留数字,并且通过将类型与该数字连接来产生名称。