我有一个不同型号的应用。其中一个模型是徽章模型,通过成就与用户建立了多对多的关系。
在我的控制器中,我有一些逻辑来检查用户是否已获得成就,然后在关系表(成就)中进行插入。在控制器中进行了一些硬编码后,我决定将逻辑转换为postgresql中的触发器。
我已经为第一枚徽章的触发器编程了:
def change
execute <<-TRIGGER
CREATE OR REPLACE FUNCTION firstbadge() RETURNS trigger AS
$$
DECLARE
BEGIN
IF (select count(id) from User where facebookid=NEW.facebookid)==0 and (select count(id) from Achievement where user_id=NEW.id and badge_id=1)==0 then
insert into Achievement(user_id,badge_id,created_at,updated_at)values(NEW.id,1,now(),now());
END IF;
RETURN NULL;
END;
$$ LANGUAGE plepgsql VOLATILE;
DROP TRIGGER IF EXISTS add_badge_user ON paper;
CREATE TRIGGER add_badge_user
BEFORE INSERT ON User FOR EACH ROW
EXECUTE PROCEDURE firstbadge();
TRIGGER
end
我的控制器中插入新用户的操作是:
if !params[:FirstName].blank? and !params[:LastName].blank?
usuario = User.new
usuario.facebookid=params[:FacebookId]
usuario.facebooktoken=params[:FacebookToken]
usuario.firstname=params[:FirstName]
usuario.lastname=params[:LastName]
usuario.identifier=params[:FirstName]
usuario.age=params[:Age]
usuario.email=params[:Email]
usuario.level=0
usuario.save
json={:Authorize=> true}
render :json => json, :status => 200
end
但是我有一点问题,我需要在我的控制器中从Achievement表(关系表)中输入最后一个ID来返回JSON。我的控制器中还有许多其他功能需要接收更新或插入的ID。
如何在postgresql上捕获触发器的结果并在我的控制器中使用它们? 我是否必须在我的控制器中进行查询以检索用户的最后成就,而不是从触发器接收它们?
谢谢。
答案 0 :(得分:0)
简单地说:你正在走出轨道哲学的一些步骤。 Rails是一个固执己见的框架,如果你不按照rails方式做事,那就会受到伤害。
首先,在rails社区中普遍接受逻辑不应属于数据库,它应属于您的应用程序。关于这一点有很多激烈的讨论,但是如果你要使用rails,你必须习惯它,因为框架就是这样设计的。所以而不是触发器,你应该在你的一个模型中使用回调。
除此之外,您的控制器代码似乎非常臃肿。鼓励控制器代码保持极薄,因为它更易于维护并与MVC架构保持一致(控制器的责任应该只是实例化模型对象,对它们执行操作,然后实例化视图)。通常的做法是将这种逻辑推向模型。
此外,它似乎并不关心命名约定。如果你没有遵循导轨的指导方针,你会失去很多魔力和奇迹,让自己的生活变得更加艰难。例如,如果您遵循惯例,则可以编写以这种方式发布的控制器代码:
usario = User.new( params[:user] )
usario.save
render json: usario, status: 200
这是3行而不是14行。
最后,所有这些都表明缺乏对框架的了解。我强烈建议你彻底(重新)阅读rails guides,以及可能有一两本好书。这将使用这个精美的rails工具,让您更准确地了解工作流程和设计。