Как вызвать метод внутри метода Rails - PullRequest
0 голосов
/ 09 ноября 2019

Я пытаюсь вызвать метод в моей пользовательской модели. У меня есть длинный метод, подобный этому:

def find_content
  def find_x
  # call api
  end
  def find_y
  #call api
  end
  content = {"x": find_x, "y": find_y}
  return content
end

Затем я пытаюсь назвать его так в моей модели:

class User < ApplicationRecord
  def User.news
    # get result of find_content
    content = find_content
    # I also tried doing User.find_content when the function was inside the model
    ## the function then passes the content variable to my UserMailer which sends emails to my users with the content
  end

Я попытался поместить свой find_content в пользовательскую модель сdef self.find_content и без самостоятельной части. Мне было интересно, где лучше всего разместить функцию, которая может быть использована в этой модели следующим образом.

Ответы [ 2 ]

2 голосов
/ 09 ноября 2019

Если бы я был там, где вы, я бы создал класс Service или класс lib, и я бы назвал его.

Не определяйте ваши методы внутри методов. Попробуйте что-то вроде этого

class MyFancyService
  def find_content
    {"x": find_x, "y": find_y}
  end

  private
  def find_x
    #code
  end

  def find_y
    #code
  end
end

И внутри вашей модели

#remember to require your libs/services class in somewhere (maybe application.rb)
class User < ApplicationRecord
  def news
     MyFancyService.new.find_content    
  end
end

Не злоупотребляйте методом Class (def self.bla), у вас должно быть больше методов экземпляра.

1 голос
/ 09 ноября 2019

Причина, по которой вы столкнулись с этой проблемой, заключается в том, что поиск контента на самом деле не является проблемой пользователя и должен быть разбит на отдельный класс, как упоминает Хорасио, но я не думаю, что класс пользователя должен знать что-либо о поиске контента. Вполне возможно, что вам нужна некоторая информация о пользователе, чтобы правильно найти контент.

Я бы предложил что-то вроде этого (при условии, что вам нужно что-то из объекта User для вызова вашего API)

class User      
  def user_stuff_needed_by_api
  end
end

class NewsAPI
    def initialize(user_stuff)
        # set stuff needed based on the user
    end
    def find_x
        # call api
        "x"
    end
    def find_y
        # call api
        "y"
    end
    def find_content
        {"x": find_x, "y": find_y}
    end
end

Затем в вашем контроллере у вас есть пользовательский объект, поэтому получите то, что вам нужно, создайте экземпляр API и сделайте ваш вызов

user_stuff = @user.user_stuff_needed_by_api
news_api = NewsAPI.new(user_stuff)
content = news_api.find_content

Если вы действительно хотите делать вызовы API внутри вашего aПользовательский экземпляр, который, я думаю, вам не следует, я бы рекомендовал передать экземпляр API через установщик, а затем делегировать find_content этому экземпляру. Ну как то так.

class User
  def set_news_api(api)
    @news_api = api
  end
  def find_content
     @news_api.find_content
  end
end

Наконец, если вы действительно хотите поместить все это в класс User, что-то вроде этого должно работать, но опять же не рекомендуется.

class User
  def self.find_x
    "xx"
    # call api
    end
  def self.find_y
    "yy"
    #call api
  end
  def find_content  
    {"x": self.class.find_x, "y": self.class.find_y}
  end
  def self.other_find_content
    {"other_x": find_x, "other_y": find_y}
  end
  def user_stuff_needed_by_api
  end
end

puts User.new.find_content
puts User.other_find_content
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...