在插入或更新操作后,在rails控制器中捕获postgres触发器



我有一个不同型号的应用程序。其中一个模型是通过成就与用户建立多对多关系的徽章模型。

在我的控制器中,我有一些逻辑来检查用户是否获得了成就,然后在关系表(成就)中进行插入。在控制器中进行一些硬编码后,我决定将逻辑带到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

但我有一个小问题,我需要最后插入的id从成就表(关系表)在我的控制器返回JSON。我的控制器中还有许多其他函数需要接收更新或插入的id。

如何在postgresql上捕获触发器的结果并在我的控制器中使用它们?我是否必须在我的控制器查询检索用户的最后成就,而不是从触发器接收它们?

谢谢。

简单地说:你正在采取一些步骤,而不是rails的哲学。Rails是一个固执己见的框架,如果你不按照Rails的方式做事,它将会受到伤害。

首先,rails社区普遍认为逻辑不应该属于数据库,它应该属于您的应用程序。关于这个有很多热烈的讨论,但如果你要使用rails,你必须习惯它,因为框架就是这样设计的。因此,应该在模型中使用回调而不是触发器。除此之外,你的控制器代码似乎非常臃肿。鼓励保持控制器代码极薄,因为它更易于维护,并且与MVC架构更一致(控制器的职责应该只是实例化模型对象,对它们执行操作,然后实例化视图)。一个常见的做法是将这样的逻辑推到模型中。

此外,似乎您并不关心命名约定。如果你不遵循rails的指导方针,你就会失去很多魔力和奇迹,让你的生活变得更加艰难。例如,如果您遵循惯例,您可以这样编写发布的控制器代码:

  usario = User.new( params[:user] )
  usario.save
  render json: usario, status: 200

这是3行而不是14行。

最后,所有这些都表明缺乏对框架的了解。我强烈建议您彻底(重新)阅读rails指南,也可能是众多好书中的一两本。这将给你一个更精确的工作流程和设计的想法,使用这个美妙的工具是rails。

最新更新