简体   繁体   English

Rails调用方法控制器与模型

[英]rails invoking methods controller vs model

I've got a rails app. 我有一个Rails应用程序。 I'm trying to finetune different models and controllers. 我正在尝试微调不同的模型和控制器。 I can make the things work, but I'm not sure if I'm doing the preferred way. 我可以使事情正常进行,但是我不确定是否正在采用首选方式。 So I have an event.rb for my own in-app fullcalendar where I can CRUD new events and have social.rb for omniauth authorization (google calendar in this case). 所以我有一个event.rb用于我自己的应用内全日历,在其中我可以CRUD新事件,并具有social.rb用于omniauth授权(在这种情况下为Google日历)。 I'm trying to display the gcal events in my fullcalendar, so based on the social.rb data (tokens, keys) I make an API call to google to get gcal event times and then display the data in events/index page (fullcalendar). 我试图在我的全日历中显示gcal事件,因此基于social.rb数据(令牌,键),我向Google进行API调用以获取gcal事件时间,然后在事件/索引页面中显示该数据(全日历) )。

Here are two of my methods I don't know how/where to put in my app. 这是我不知道如何/在哪里放置应用程序的两种方法。 My questions (I have 3 as they are closely connected): 我的问题(我有3个紧密联系):

  • Method types. 方法类型。 As I see init_google_api_calendar_client should be a class method if I put it into the social.rb (I'm not even sure if I should place it there). 如我所见,如果将init_google_api_calendar_client放入social.rb中,则它应该是一个类方法(甚至不确定是否应将其放置在此处)。 For the get_busy_events I simply can't decide what type to use. 对于get_busy_events,我根本无法决定使用哪种类型。
  • I guess I should put these method in a model/module, but which one (social/event/something else)? 我想我应该将这些方法放在模型/模块中,但是哪一个(社交/事件/其他)?
  • How should I invoke the methods? 我应该如何调用这些方法?

events_controller events_controller

  def index
    @user = current_user
    @google = @user.socials.where(provider: "google_oauth2").first
    @client = Social.init_google_api_calendar_client(@google) ### Is this the proper way to call this method?
    @get_busy_times = #####how to call the get_buys_events method?
    @event = Event.new
    @events = Event.allevents(current_user)
    respond_to do |format|
      format.html
      format.json { render json: @events }
      format.js
    end
  end

social.rb social.rb

  def self.init_google_api_calendar_client(google_account)
    #method only called if google_oauth2 social exists
    client = Google::APIClient.new
    client.authorization.access_token = google_account.token
    client.authorization.client_id = ENV['GOOGLE_API_KEY']
    client.authorization.client_secret = ENV['GOOGLE_API_SECRET']
    client.authorization.refresh_token = google_account.refresh_token
    return client
  end

Where to put this method? 该方法放在哪里? Should be class/instance? 应该是类/实例吗? How should be invoked? 应该如何调用?

  def get_busy_events(client)
    service = client.discovered_api('calendar', 'v3')
    result = client.execute(
      api_method: service.freebusy.query,
      body_object: { timeMin: start_at,
                     timeMax: end_at,
                     items: items},
      headers: {'Content-Type' => 'application/json'})
  end

You're asking a good question and in my experience there isn't a universally adopted convention in the Rails community for where to put code that makes server-side API calls to 3rd party services. 您问的是一个很好的问题,根据我的经验,Rails社区中没有普遍采用的约定,该约定将将服务器端API调用的代码放置到第三方服务中。

When your app uses external APIs in ways that are okay to be asynchronous, it would be appropriate to invoke these calls using ActiveJob or gems like sidekiq directly. 当您的应用以可以异步的方式使用外部API时, sidekiq直接使用ActiveJob或诸如sidekiq gem调用这些调用。 Here's a decent write-up (see the section labeled "Talking with external APIs"): https://blog.codeship.com/how-to-use-rails-active-job/ 这是一个不错的文章(请参阅标有“与外部API交流”的部分): https : //blog.codeship.com/how-to-use-rails-active-job/

But, if you are building an app that truly dependent on the 3rd-party API and asynchronous calls don't provide you much benefit, then I suggest defining a different type of class that is neither a model, view, nor controller. 但是,如果您要构建真正依赖于第三方API的应用程序,并且异步调用不能给您带来太多好处,那么我建议定义一个既不是模型,视图也不是控制器的不同类型的类。 A common practice to follow when there aren't already gems to meet your needs is to write a ruby wrapper class for the API saved under the lib folder. 当还没有满足您需要的宝石时,可以遵循的常见做法是为lib文件夹下保存的API编写ruby包装器类。 Keep your model methods scoped towards logic that requires database interactivity. 使模型方法的范围限定在需要数据库交互的逻辑上。 Invoke model methods from your controller as well as webservice methods defined in your wrapper class. 从您的控制器以及包装类中定义的Web服务方法中调用模型方法。

Good luck! 祝好运!

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

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