【问题标题】:Catch postgres trigger in rails controller after insert or update operation插入或更新操作后在 Rails 控制器中捕获 postgres 触发器
【发布时间】:2013-03-27 18:55:26
【问题描述】:

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

在我的控制器中,我有一些逻辑来检查用户是否获得了成就,然后在关系表(成就)中进行插入。在控制器中进行一些硬编码后,我决定将逻辑带到 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 上捕获触发器的结果并在我的控制器中使用它们? 我是否必须在我的控制器中进行查询以检索用户的最后成就,而不是从触发器中接收它们?

谢谢。

【问题讨论】:

    标签: ruby-on-rails postgresql triggers controllers


    【解决方案1】:

    简而言之:您正在采取一些措施脱离 Rails 的理念。 Rails 是一个固执己见的框架,如果你不按照 Rails 的方式做事,就会受到伤害。

    首先,rails 社区普遍认为逻辑不应该属于数据库,它应该属于你的应用程序。关于这个有很多激烈的讨论,但如果你要使用 Rails,你必须习惯它,因为框架就是这样设计的。所以您应该在其中一个模型中使用回调而不是触发器

    除此之外,您的控制器代码似乎非常臃肿。鼓励保持控制器代码非常精简,因为它更易于维护并且与 MVC 架构保持一致(控制器的职责应该只是实例化模型对象,对其执行操作,然后实例化视图)。一种常见的做法是将此类逻辑下推到模型中。

    此外,您似乎一点也不关心命名约定。如果您不遵守有关此的 Rails 指南,您将失去很多魔法和奇迹,并使您自己的生活变得更加艰难。例如,如果您遵循约定,您可以这样编写您发布的控制器代码:

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

    那是 3 行而不是 14 行。

    最后,所有这些都表明缺乏对框架的了解。我强烈建议您彻底(重新)阅读rails guides,可能还有许多好书中的一两本。这将让您更准确地了解工作流程和使用 Rails 这个奇妙的工具进行设计。

    【讨论】:

    • 抱歉约定俗成,我收到每个参数以在 http 请求中单独创建一个新用户,mi 应用程序只是移动应用程序的背面,并且参数由客户端定义:)跨度>
    • 在这种情况下,您可以使用normalize_params 方法在应用程序内部“翻译”传入的参数并返回。
    • 非常感谢您的帮助:)
    • err... 我不介意 -1,但稍微解释一下就好了
    • 我没有投反对票。正如你所建议的,我在我的模型中编写了一个回调并且它正在工作:) 为我节省了很多工作。一个例子:after_create :give_achievements private def give_achievements ~ end 谢谢 :)
    猜你喜欢
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2019-07-28
    • 2016-10-13
    相关资源
    最近更新 更多