简体   繁体   English

在Rails中使用红宝石中的私有方法

[英]Working with private methods in ruby on rails

I've two private methods in my event.rb model an I want these two methods should invoke on two different actions in my events controller. 我的event.rb模型中有两个私有方法,我希望这两个方法应在事件控制器中的两个不同操作上调用。

event.rb event.rb

    private 

  def create_notification_on_accept
    self.notifications.create(action_type: "Accept", actor_id: participant.id,
    user_id: user_id)
 end

 def create_notification_on_reject
  self.notifications.create(action_type: "Reject", actor_id: participant.id,
  user_id: user_id)
end

events_controller.rb events_controller.rb

  def accept_invitation
   @participants.where(user_id: current_user.id).update_all(is_attending: true)
   render "update"
 end

def reject_invitation
 @participants.where(user_id: current_user.id).update_all(is_attending: false)
 render "update"
end

How can I call these two private mathods in my controller.? 如何在控制器中调用这两个私有方法。

Any suggestions are helpful. 任何建议都是有帮助的。

There are no private methods in ruby (as we all know as in Java), you can call them with the Object#send method. ruby中没有私有方法(众所周知,在Java中),您可以使用Object#send方法调用它们。

http://ruby-doc.org/core-2.2.0/Object.html#method-i-send http://ruby-doc.org/core-2.2.0/Object.html#method-i-send

You can make them class methods to call them in your controllers. 您可以使它们成为类方法以在控制器中调用它们。

 private 

 def self.create_notification_on_accept(event)
   # I don't know where are you getting participant id, so pass it if you need
   # additionally, if they are available on event object then you could do
   # event.participant.id, event.user_id since the background of the code is not given
   # hence I'm making some assumptions 
   event.notifications.create(action_type: "Accept", actor_id: participant.id,
   user_id: user_id)
 end

 def self.create_notification_on_reject(event)
   event.notifications.create(action_type: "Reject", actor_id: participant.id,
 user_id: user_id)
 end

And in your controller you can do this 在您的控制器中,您可以执行此操作

def accept_invitation
   #find event so you can pass it as a param
   Event.create_notification_on_accept(event)
   @participants.where(user_id: current_user.id).update_all(is_attending: true)
   render "update"
end

However, a better thing to do this would be to have callbacks instead of class methods. 但是,更好的方法是使用回调而不是类方法。 That way you can reduce the overhead of calling the method everywhere, instead you can leave it onto the model to know when to call. 这样,您可以减少在任何地方调用该方法的开销,而可以将其留在模型上以知道何时调用。

You can not call private methods, there is no way for it directly. 您不能调用私有方法,没有直接方法。 You could create wrappers that are those methods but as public. 您可以创建这些方法的包装器,但将其公开。 Best solution move them to public segemnt 最好的解决方案将它们移到公共领域

There are a number of ways to get these methods to fire when your particular controller actions are fired. 当您的特定控制器动作被触发时,有多种方法可以使这些方法触发。

  1. Make them callbacks, these could fire when you save the event. 使它们成为回调,保存事件时可能会触发这些回调。 See http://guides.rubyonrails.org/active_record_callbacks.html 请参阅http://guides.rubyonrails.org/active_record_callbacks.html

  2. Put the methods in a service layer object, which updates the participants, and creates the notifications. 将方法放在服务层对象中,该对象将更新参与者并创建通知。 In this case your controller methods could create a new Reply instance. 在这种情况下,您的控制器方法可以创建一个新的Reply实例。 The Reply class could then have methods to update_participants, and create_notification 然后,Reply类可以具有update_participants和create_notification的方法。

In general if you want to call, or test private methods, then think of this as an indicator that these methods want to be public methods, probably in another class. 通常,如果您要调用或测试私有方法,则可以将此视为这些方法希望是公共方法(可能在另一个类中)的指示符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM