hyperstack-org / hyperstack-org/hyperstack
Client-side ability to refresh a scope
- Ngôn ngữ chính
- JavaScript
- Star
- 538
- Fork
- 41
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Mô tả
In some circumstances, it would be very useful for the client to 'refresh' a scope on a model where the client believed a refresh would render new results.
An example would be where the client performed an action (called an API for an example) which the programmer knew modified data outside of the current scope (or the scopes children or even further down the parent-child tree from the scope) and when the API promise resolved, a method could be called which would effectively cause the scope the be refreshed and the UI re-rendered if needed.
Here is an example:
We have a simple model with a scope which is being used to list all workouts for a user used :
```
class Workout < ApplicationRecord
has_many :exercises
belongs_to :user
scope :for_user, ->(id) { where(user_id: id) }
end
```
And an API call based on a Button being pressed in the UI:
```
def generate_workout
HTTP.get("/bridge/generate_workout",
data: { user_id: user.id }).then do |resp|
# alert "pass"
end.fail do |resp|
puts resp.json
alert "failed to generate workout"
end
end
```
Which calls a controller API method (simplified for this example):
```
def generate_workout
params.permit(:user_id)
user_id = params[:user_id]
user = User.find user_id
value = user.generate_workout!
return_code = value ? 200 : 400
render json: { error: @error || "" }, status: return_code
end
```
Which in turn calls a method on a model:
```
def generate_workout!
# select build_workout_for_user is a SQL function whcih acts outside of the Rails context
value = ActiveRecord::Base.connection.execute("select build_workout_for_user(#{self.id})").values
return false if value.first.first == -1
return true
end
```
The code above all work's but the user's list of Workouts do not refresh as the SQL function which is building a workout (making many changes to many tables) happens outside of the Rails context at the Postgres level.
The workaround (today) is to push a notification to the client (from the API method) like this:
```
def generate_workout!
value = ActiveRecord::Base.connection.execute("select build_workout_for_user(#{self.id})").values
return false if value.first.first == -1
workout = Workout.for_user(self.id).last
ReactiveRecord::Broadcast.after_commit :create, workout
return true
end
```
The problem with this workaround is that only the new Workout is pushed (so it is displayed), but the SQL function actually changed other data as well which is not refreshed, nor are the fields of the new Workout fetched - just the fact that a new one has been created is displayed in the UI.
The proposed solution should be that the client could request that a scope be refreshed (in this case, when the promise resolves).
```
HTTP.get("/bridge/generate_workout",
data: { user_id: user.id }).then do |resp|
# now refresh the scope
Workout.for_user(user.id).reload! # <---- this new line
end.fail do |resp|
puts resp.json
alert "faild to generate workout"
end
```
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.