-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DEV: Refactor themes controller to services part 1 #29631
base: main
Are you sure you want to change the base?
DEV: Refactor themes controller to services part 1 #29631
Conversation
Need to sort out remote theme git policy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is still a draft, but I left some comments, some are just me thinking out loud, I’ll be glad to get your feedback 😁
private | ||
|
||
def ban_in_allowlist_mode | ||
Theme.allowed_remote_theme_ids.nil? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can’t be an empty array? It looks like it should return an array 😅 We could maybe use #blank?
instead of #nil?
just to be sure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's weird, sometimes it's nil and sometimes it's an empty array...but yes I think blank could work here
Lines 258 to 265 in dd4755b
def self.allowed_remote_theme_ids | |
return nil if GlobalSetting.allowed_theme_repos.blank? | |
get_set_cache "allowed_remote_theme_ids" do | |
urls = GlobalSetting.allowed_theme_repos.split(",").map(&:strip) | |
Theme.joins(:remote_theme).where("remote_themes.remote_url in (?)", urls).pluck(:id) | |
end | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annoyingly this return nil
seems to be important, if Theme.joins(:remote_theme).where("remote_themes.remote_url in (?)", urls).pluck(:id)
returns an [] we don't care for the purposes of other existing code. Not sure if that's intentional or not, don't want to touch it for now
app/services/themes/create.rb
Outdated
# TODO (martin) Ask loic about this, the old theme controller expected the | ||
# errors from the theme model save to be shown to the user. | ||
def save_theme(theme:) | ||
theme.save! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, either use a rescue
block and call fail!
inside it or just call save
and check for any errors (and call fail!
😁), as we discussed IIRC.
It seems we should be able to do something like that in the model
step, though:
Theme.create(params.slice(:name, :user_id, :user_selectable, :color_scheme_id, :component)) do |theme|
params.theme_fields.each do |field|
theme.set_field(**field)
end
end
The only problem is still that Theme#set_field
raises because it does validations that should be done in ThemeField
. Maybe a small refactor (moving validations where they should happen) could resolve that situation.
Maybe that’s an approach we could apply for updates too (Model.find_by(…).tap {|model| model.update(…) }
), I don’t know 🤔
Otherwise, we could implement a new step, something like persist_model :my_model
, it would call save
on it, check if the model is both valid and persisted, if that’s not the case, it would stop the execution flow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure I could try a refactor of set_field
, and otherwise do the rescue/error check for save. persist_model sounds nice too 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just went for the theme.save/fail! model errors for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m working on adding a new step to handle exceptions: #29660.
That would probably come in handy in a situation like this 😁
@martin-brennan ok, so now that #29660 has been merged, we can do this (just tested locally, did not a lot of tests though, but it’s working): transaction do
try(Theme::InvalidFieldTargetError, Theme::InvalidFieldTypeError) do
model :theme, :create_theme
end
step :update_default_theme
step :log_theme_change
end
def create_theme(params:)
Theme.create(params.slice(:name, :user_id, :user_selectable, :color_scheme_id, :component)) do |theme|
params.theme_fields.to_a.each { |field| theme.set_field(**field.symbolize_keys) }
end
end Instead of having 3 steps with their own error logic/handling, we just use one and everything’s covered 😁 In the controller, I see that everything’s matched through |
Nice that's great @Flink thanks for letting me know, will do some further refactors with this now 👍 Also I need to go and make service specs for all the services I've added 😅 The functionality is covered by controller specs but I still want the low level ones too |
Great! Let me know if you need a hand or when you want another review 😁 |
This commit starts to introduce services to replace actions in the
ThemesController. We will start with the low langing fruit:
Endpoints like
#import
and#update
will be much harder.Also, the https://github.com/discourse/discourse-theme-creator plugin
overrides some of these controller actions directly, so we need
to be careful.