Ruby on rails 在不触发多个渲染/重定向的情况下从控制器内的部分调用数据

Ruby on rails 在不触发多个渲染/重定向的情况下从控制器内的部分调用数据,ruby-on-rails,Ruby On Rails,我正在尝试从我的一个控制器中的一个部分检索数据,而不会导致重定向/渲染问题 这就是create方法在控制器中的样子,它正在调用另一个函数 def create @finding = @findings.new(finding_params) respond_to do |format| if @finding.save if @project_notifications.where(category: "XXXXXXX").any? notify_us

我正在尝试从我的一个控制器中的一个部分检索数据,而不会导致重定向/渲染问题

这就是create方法在控制器中的样子,它正在调用另一个函数

def create
  @finding = @findings.new(finding_params)
  respond_to do |format|
    if @finding.save
      if @project_notifications.where(category: "XXXXXXX").any?
        notify_users(1)
      end
      flash[:notice] = 'Finding was successfully created.'
    else
      helpers.show_errors_for(@finding)
    end
    format.html { redirect_back fallback_location: root_path }
    format.js { head :no_head }
  end
end
notify_users函数如下所示:

def notify_users(notification_type)
  if notification_type == 1
    html_body = render(partial: 'findings/added_finding')
    subject = "XXXXXXX."

    @project_notifications.each do |notification|
      NotificationWorker.perform_async(html_body, notification.user, subject)
    end
  end
end
问题是我遇到了多重渲染/重定向错误。有没有一种方法可以在不再次调用render的情况下从部分检索数据?

在notify_users方法not函数中,您在此处调用render:

在create方法中,您在此处调用redirect:

因此,该声明似乎:

在此操作中多次调用渲染和/或重定向

…是真的

我想您可以将notify_用户移动到NotifyUserService并在那里进行渲染。当我在服务中渲染时,我没有渲染和/或重定向被多次调用的问题

因此,您可以做如下操作:

#app/services/notify_user_service.rb
class NotifyUserService

  include ActsAsRendering

  class << self 

    def call(args={})
      new(args).call
    end

  end

  def initialize(args)
    args.each do |k,v|
      class_eval do 
        attr_accessor k
      end
      send("#{k}=",v)
    end
  end

  def call 
    case notification_type
    when :some_notification_type
      html_body = render_partial('findings/added_finding')
      subject = "XXXXXXX."

      project_notifications.each do |notification|
        NotificationWorker.perform_async(html_body, notification.user, subject)
      end          
    end
  end

  def some_information
    case notification_type
      when :some_notification_type
        'some notification information'
      else
        'default notification information'
      end
  end

end
当然,这假设NotifyUserService知道如何呈现。我忘记了Rails 5/6世界中渲染的状态。但是,为了告诉我的服务如何渲染,我有一个名为ActsAsRendering的模块:

您会注意到,我创建了一个render_partial方法,并使用该方法而不是render。render_partial方法将NotifyUserService实例作为本地实例传入。这样,在我看来,我可以做以下事情:

#app/views/findings/added_finding.html.haml
- @presenter = local_assigns[:presenter] if local_assigns[:presenter]

#some-document-id
  .some-presenter-information
    @presenter.some_information
现在视图将在html中显示“一些通知信息”。通过这种方式,我可以将所有视图逻辑推回到演示者中,我的视图将变得100%无逻辑。

在notify_users方法不起作用时,您在此处调用render:

在create方法中,您在此处调用redirect:

因此,该声明似乎:

在此操作中多次调用渲染和/或重定向

…是真的

我想您可以将notify_用户移动到NotifyUserService并在那里进行渲染。当我在服务中渲染时,我没有渲染和/或重定向被多次调用的问题

因此,您可以做如下操作:

#app/services/notify_user_service.rb
class NotifyUserService

  include ActsAsRendering

  class << self 

    def call(args={})
      new(args).call
    end

  end

  def initialize(args)
    args.each do |k,v|
      class_eval do 
        attr_accessor k
      end
      send("#{k}=",v)
    end
  end

  def call 
    case notification_type
    when :some_notification_type
      html_body = render_partial('findings/added_finding')
      subject = "XXXXXXX."

      project_notifications.each do |notification|
        NotificationWorker.perform_async(html_body, notification.user, subject)
      end          
    end
  end

  def some_information
    case notification_type
      when :some_notification_type
        'some notification information'
      else
        'default notification information'
      end
  end

end
当然,这假设NotifyUserService知道如何呈现。我忘记了Rails 5/6世界中渲染的状态。但是,为了告诉我的服务如何渲染,我有一个名为ActsAsRendering的模块:

您会注意到,我创建了一个render_partial方法,并使用该方法而不是render。render_partial方法将NotifyUserService实例作为本地实例传入。这样,在我看来,我可以做以下事情:

#app/views/findings/added_finding.html.haml
- @presenter = local_assigns[:presenter] if local_assigns[:presenter]

#some-document-id
  .some-presenter-information
    @presenter.some_information
现在视图将在html中显示“一些通知信息”。通过这种方式,我可以将所有视图逻辑推回到演示者中,我的视图将变得100%无逻辑。

您可以将其用于此用例:

def notify_users(notification_type)
  if notification_type == 1
    html_body = render_to_string(partial: 'findings/added_finding', layout: false)
    subject = "XXXXXXX."

    @project_notifications.each do |notification|
      NotificationWorker.perform_async(html_body, notification.user, subject)
    end
  end
end
这样,您将获得HTML的字符串化表示,以便在其他地方使用。让我知道你是如何做到这一点的——我很想知道这是否适合你的用例。如果有任何问题,请立即提问:

您可以在本用例中使用:

def notify_users(notification_type)
  if notification_type == 1
    html_body = render_to_string(partial: 'findings/added_finding', layout: false)
    subject = "XXXXXXX."

    @project_notifications.each do |notification|
      NotificationWorker.perform_async(html_body, notification.user, subject)
    end
  end
end

这样,您将获得HTML的字符串化表示,以便在其他地方使用。让我知道你是如何做到这一点的——我很想知道这是否适合你的用例。如果有任何问题,请发问:

我也注意到了这一点。是否有其他方法可以在不触发渲染的情况下从部分检索数据?将notify_用户移动到NotifyUserService?我不确定我是否听懂了。您是否建议将该函数重命名为该函数?创建另一个工人?不要跟着。谢谢!如果我还需要的话,我会考虑搬到这样的地方。不过,要知道的信息太多了!我也注意到了。是否有其他方法可以在不触发渲染的情况下从部分检索数据?将notify_用户移动到NotifyUserService?我不确定我是否听懂了。您是否建议将该函数重命名为该函数?创建另一个工人?不要跟着。谢谢!如果我还需要的话,我会考虑搬到这样的地方。不过,要知道的信息太多了!这实际上解决了它。我真的很感激!!太棒了,很高兴听到它@LewlSauce-如果你觉得它回答了这个问题,请随意给这个答案打勾,将其标记为接受:这实际上解决了它。我真的很感激!!太棒了,很高兴听到它@LewlSauce-如果你觉得它回答了问题,请随意给这个答案打勾,将其标记为已接受:
def notify_users(notification_type)
  if notification_type == 1
    html_body = render_to_string(partial: 'findings/added_finding', layout: false)
    subject = "XXXXXXX."

    @project_notifications.each do |notification|
      NotificationWorker.perform_async(html_body, notification.user, subject)
    end
  end
end