我有一种目前正常运行的方法,但我想知道是否有更好的方法。
有一个项目(歌曲)队列,其中索引增加并相应地更新。
这是我目前的代码:
def self.get_next_schedule_track(schedule)
begin
# get current position
current_position = schedule.current_position
current_schedule_track = scheduled_track_at_position(schedule, current_position)
# check if next position is valid, otherwise pick random track
next_position = current_position + 1
next_schedule_track = scheduled_track_at_position(schedule, next_position)
if next_schedule_track.nil?
random_track = Track.where.not(id: current_schedule_track.track.id).order("RANDOM()").first
ScheduleTrack.create(track: random_track, schedule: schedule)
next_schedule_track = scheduled_track_at_position(schedule, next_position)
end
# advance current_position
schedule.current_position = next_position
schedule.save
# update state of schedule tracks
current_schedule_track.update(state: 'playing') unless current_schedule_track.nil?
next_schedule_track.update(state: 'next') unless next_schedule_track.nil?
# if previous track set state to played
previous_schedule_track = scheduled_track_at_position(schedule, current_position - 1)
previous_schedule_track.update(state: 'played') unless previous_schedule_track.nil?
# broadcast new current position
ActionCable.server.broadcast "schedule_channel", { title: 'next position', body: next_schedule_track.id }
# return next_track
next_track = next_schedule_track.track
Rails.logger.debug "next_track = #{next_track.title}"
next_schedule_track
rescue Exception => e
Rails.logger.error ("[ScheduleService.get_next_schedule_track] there was an error = #{e}")
nil
end
end
这确实有效且易于阅读,但它也会产生多个SQL请求,所以我想知道是否有更好的方法?
以下是显示所有请求的日志。
starting get next schedule
ScheduleTrack Load (0.6ms) SELECT "schedule_tracks".* FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND "schedule_tracks"."position" = $2 ORDER BY "schedule_tracks"."position" ASC [["schedule_id", 22], ["position", 2077]]
ScheduleTrack Load (0.8ms) SELECT "schedule_tracks".* FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND "schedule_tracks"."position" = $2 ORDER BY "schedule_tracks"."position" ASC [["schedule_id", 22], ["position", 2078]]
Track Load (0.3ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = $1 LIMIT $2 [["id", 74020682], ["LIMIT", 1]]
Track Load (0.4ms) SELECT "tracks".* FROM "tracks" WHERE ("tracks"."id" != $1) ORDER BY RANDOM() LIMIT $2 [["id", 74020682], ["LIMIT", 1]]
(0.1ms) BEGIN
ScheduleTrack Load (2.6ms) SELECT "schedule_tracks".* FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND ("schedule_tracks"."position" IS NOT NULL) ORDER BY "schedule_tracks"."position" DESC LIMIT $2 [["schedule_id", 22], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "schedule_tracks" ("position", "track_id", "schedule_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["position", 2078], ["track_id", 416171102], ["schedule_id", 22], ["created_at", "2017-10-30 12:04:22.470182"], ["updated_at", "2017-10-30 12:04:22.470182"]]
[ActionCable] Broadcasting to schedule_channel: {:title=>"created track", :body=>4984}
(0.6ms) COMMIT
ScheduleTrack Load (0.8ms) SELECT "schedule_tracks".* FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND "schedule_tracks"."position" = $2 ORDER BY "schedule_tracks"."position" ASC [["schedule_id", 22], ["position", 2078]]
(0.2ms) BEGIN
SQL (0.3ms) UPDATE "schedules" SET "current_position" = $1, "updated_at" = $2 WHERE "schedules"."id" = $3 [["current_position", 2078], ["updated_at", "2017-10-30 12:04:22.482505"], ["id", 22]]
(0.4ms) COMMIT
(0.2ms) BEGIN
SQL (0.5ms) UPDATE "schedule_tracks" SET "state" = $1, "updated_at" = $2 WHERE "schedule_tracks"."id" = $3 [["state", "playing"], ["updated_at", "2017-10-30 12:04:22.487240"], ["id", 4983]]
(0.5ms) SELECT COUNT(*) FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND ("schedule_tracks"."position" = 2077) [["schedule_id", 22]]
(0.6ms) COMMIT
(0.5ms) BEGIN
SQL (1.2ms) UPDATE "schedule_tracks" SET "state" = $1, "updated_at" = $2 WHERE "schedule_tracks"."id" = $3 [["state", "next"], ["updated_at", "2017-10-30 12:04:22.504735"], ["id", 4984]]
(2.0ms) SELECT COUNT(*) FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND ("schedule_tracks"."position" = 2078) [["schedule_id", 22]]
(0.9ms) COMMIT
ScheduleTrack Load (0.5ms) SELECT "schedule_tracks".* FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND "schedule_tracks"."position" = $2 ORDER BY "schedule_tracks"."position" ASC [["schedule_id", 22], ["position", 2076]]
(0.2ms) BEGIN
SQL (0.5ms) UPDATE "schedule_tracks" SET "state" = $1, "updated_at" = $2 WHERE "schedule_tracks"."id" = $3 [["state", "played"], ["updated_at", "2017-10-30 12:04:22.519705"], ["id", 4982]]
(0.6ms) SELECT COUNT(*) FROM "schedule_tracks" WHERE "schedule_tracks"."schedule_id" = $1 AND ("schedule_tracks"."position" = 2076) [["schedule_id", 22]]
(0.6ms) COMMIT
[ActionCable] Broadcasting to schedule_channel: {:title=>"next position", :body=>4984}
Track Load (0.4ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = $1 LIMIT $2 [["id", 416171102], ["LIMIT", 1]]
next_track = New York
有关最佳方法的建议将不胜感激 - 是否有更好的方法,或者这是一个很好的解决方案。
非常感谢!
答案 0 :(得分:1)
在rails中编写干代码的最佳方法是执行以下操作:
<强> 1。使用MVC架构
这需要在模型,视图和控制器之间分离代码。基本概念是在Model Class中创建自己的自定义方法,这样您就可以多次调用该方法并在代码中保存很多行。
例如,
# check if next position is valid, otherwise pick random track
next_position = current_position + 1
next_schedule_track = scheduled_track_at_position(schedule, next_position)
将此代码移至Position.rb
模型
def check_validity
next_position = self + 1
// perform the rest of your validity checks in hear
// I don't know how to get hear the scheduled_track_at_position
end
而对于其余部分,在此我发现与Track
模型,SceduleTrack
模型和其他模型相关的内容......我相信你会通过scheduled_track_at_position
来听取因为它是同一模型中的一种方法,它看起来像我一样混乱。
if next_schedule_track.nil?
random_track = Track.where.not(id: current_schedule_track.track.id).order("RANDOM()").first
ScheduleTrack.create(track: random_track, schedule: schedule)
next_schedule_track = scheduled_track_at_position(schedule, next_position)
end
在Track.rb
中创建random_track
类方法
def self.random_track(schedule)
self.where.not(id: schedule.track.id).order("RANDOM()").first
end
您可以使用
从Song.rb
调用该方法
Track.random_track(current_schedule_track.track.id)
但我可以通过在Song.rb
def track_id
current_schedule_track.track.id
end
所以也许这可能会成功
Track.random_track(track_id)
<强> 2。使用继承和混合
干掉更多代码的第二种方法,不仅是将代码从Song.rb
模块移动到Track.rb
或其他Models
中的相应方法,如果某个方法应该在Models
上使用多个方法,但Model
已经有parent
,则创建Module
和extend
或include
Module
Class
方法res.forEach((v, i) => {
//Add the point here because this is where your processing happens I guess?
this.points++;
});
//Move it outside of your loop
$timer = Observable.timer(100).subscribe((i) => {// $timer as a local variable. 1000/60 might be better as it will refresh for every frame.
this.percentageCom = (this.points / this.PointsAdded) * 100;
if (this.percentageCom === 100) {
// this.isHidden = true;
this.$timer.unsubscribe();
}
});
在此post
中详细了解此信息如果您还有其他问题,请问我。