rails 调用方法控制器与模型
rails invoking methods controller vs model
我有一个 rails 应用程序。我正在尝试微调不同的模型和控制器。我可以让事情正常进行,但我不确定我是否在做我喜欢的方式。所以我有一个 event.rb 用于我自己的应用程序内全日历,我可以在其中 CRUD 新事件并具有 social.rb 用于 omniauth 授权(在这种情况下为 google 日历)。我正在尝试在我的全日历中显示 gcal 事件,因此基于 social.rb 数据(令牌、密钥),我对 google 进行了 API 调用以获取 gcal 事件时间,然后在 events/index 页面(完整日历)中显示数据。
这是我不知道 how/where 放入我的应用程序的两种方法。我的问题(我有 3 个,因为它们紧密相关):
- 方法类型。如我所见,如果我将 init_google_api_calendar_client 放入 social.rb 中,它应该是一个 class 方法(我什至不确定是否应该将它放在那里)。对于 get_busy_events 我根本无法决定使用什么类型。
- 我想我应该将这些方法放在 model/module 中,但是哪一个(social/event/something 其他)?
- 我应该如何调用这些方法?
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
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
这个方法放在哪里?应该是class/instance?应该如何调用?
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
你问的是一个很好的问题,根据我的经验,Rails 社区没有普遍采用的约定来放置进行 server-side API 调用的代码到第 3 方服务。
当您的应用以可以异步的方式使用外部 API 时,使用 ActiveJob
或 sidekiq
等 gem 直接调用这些调用是合适的。这是一个不错的 write-up(参见标记为 "Talking with external APIs" 的部分):https://blog.codeship.com/how-to-use-rails-active-job/
但是,如果您构建的应用程序真正依赖于第 3 方 API 并且异步调用不会给您带来太多好处,那么我建议定义一种不同类型的 class这既不是模型、视图,也不是控制器。当还没有满足您需要的 gem 时,通常要遵循的做法是为保存在 lib
文件夹下的 API 编写一个 ruby 包装器 class。将模型方法的范围限定在需要数据库交互的逻辑范围内。从控制器调用模型方法以及包装器中定义的网络服务方法 class.
祝你好运!
我有一个 rails 应用程序。我正在尝试微调不同的模型和控制器。我可以让事情正常进行,但我不确定我是否在做我喜欢的方式。所以我有一个 event.rb 用于我自己的应用程序内全日历,我可以在其中 CRUD 新事件并具有 social.rb 用于 omniauth 授权(在这种情况下为 google 日历)。我正在尝试在我的全日历中显示 gcal 事件,因此基于 social.rb 数据(令牌、密钥),我对 google 进行了 API 调用以获取 gcal 事件时间,然后在 events/index 页面(完整日历)中显示数据。
这是我不知道 how/where 放入我的应用程序的两种方法。我的问题(我有 3 个,因为它们紧密相关):
- 方法类型。如我所见,如果我将 init_google_api_calendar_client 放入 social.rb 中,它应该是一个 class 方法(我什至不确定是否应该将它放在那里)。对于 get_busy_events 我根本无法决定使用什么类型。
- 我想我应该将这些方法放在 model/module 中,但是哪一个(social/event/something 其他)?
- 我应该如何调用这些方法?
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
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
这个方法放在哪里?应该是class/instance?应该如何调用?
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
你问的是一个很好的问题,根据我的经验,Rails 社区没有普遍采用的约定来放置进行 server-side API 调用的代码到第 3 方服务。
当您的应用以可以异步的方式使用外部 API 时,使用 ActiveJob
或 sidekiq
等 gem 直接调用这些调用是合适的。这是一个不错的 write-up(参见标记为 "Talking with external APIs" 的部分):https://blog.codeship.com/how-to-use-rails-active-job/
但是,如果您构建的应用程序真正依赖于第 3 方 API 并且异步调用不会给您带来太多好处,那么我建议定义一种不同类型的 class这既不是模型、视图,也不是控制器。当还没有满足您需要的 gem 时,通常要遵循的做法是为保存在 lib
文件夹下的 API 编写一个 ruby 包装器 class。将模型方法的范围限定在需要数据库交互的逻辑范围内。从控制器调用模型方法以及包装器中定义的网络服务方法 class.
祝你好运!