@@ -69,7 +69,7 @@ class ActionControllerActionMethod extends Method, HTTP::Server::RequestHandler:
6969 * `<sourcePrefix>app/views/<subpath>/<method_name>.html.erb`.
7070 */
7171 ErbFile getDefaultTemplateFile ( ) {
72- controllerTemplatesFolder ( this .getControllerClass ( ) , result . getParentContainer ( ) ) and
72+ controllerTemplateFile ( this .getControllerClass ( ) , result ) and
7373 result .getBaseName ( ) = this .getName ( ) + ".html.erb"
7474 }
7575
@@ -220,25 +220,40 @@ class ActionControllerHelperMethod extends Method {
220220 * if such a controller class exists.
221221 */
222222ActionControllerControllerClass getAssociatedControllerClass ( ErbFile f ) {
223- controllerTemplatesFolder ( result , f .getParentContainer ( ) )
223+ // There is a direct mapping from template file to controller class
224+ controllerTemplateFile ( result , f )
225+ or
226+ // The template `f` is a partial, and it is rendered from within another
227+ // template file, `fp`. In this case, `f` inherits the associated
228+ // controller classes from `fp`.
229+ f .isPartial ( ) and
230+ exists ( RenderCall r , ErbFile fp |
231+ r .getLocation ( ) .getFile ( ) = fp and
232+ r .getTemplateFile ( ) = f and
233+ result = getAssociatedControllerClass ( fp )
234+ )
224235}
225236
237+ // TODO: improve layout support, e.g. for `layout` method
238+ // https://guides.rubyonrails.org/layouts_and_rendering.html
226239/**
227- * Holds if `templatesFolder` is in the correct location to contain template
228- * files "belonging" to the given `ActionControllerControllerClass`, according
229- * to Rails conventions.
240+ * Holds if `templatesFile` is a viable file "belonging" to the given
241+ * `ActionControllerControllerClass`, according to Rails conventions.
230242 *
231- * In particular, this means that an action method in `cls` will by default
232- * render a correspondingly named template file within `templatesFolder `.
243+ * This handles mappings between controllers in `app/controllers/`, and
244+ * templates in `app/views/` and `app/views/layouts/ `.
233245 */
234- predicate controllerTemplatesFolder ( ActionControllerControllerClass cls , Folder templatesFolder ) {
246+ predicate controllerTemplateFile ( ActionControllerControllerClass cls , ErbFile templateFile ) {
235247 exists ( string templatesPath , string sourcePrefix , string subPath , string controllerPath |
236248 controllerPath = cls .getLocation ( ) .getFile ( ) .getRelativePath ( ) and
237- templatesPath = templatesFolder .getRelativePath ( ) and
249+ templatesPath = templateFile . getParentContainer ( ) .getRelativePath ( ) and
238250 // `sourcePrefix` is either a prefix path ending in a slash, or empty if
239251 // the rails app is at the source root
240252 sourcePrefix = [ controllerPath .regexpCapture ( "^(.*/)app/controllers/(?:.*?)/(?:[^/]*)$" , 1 ) , "" ] and
241253 controllerPath = sourcePrefix + "app/controllers/" + subPath + "_controller.rb" and
242- templatesPath = sourcePrefix + "app/views/" + subPath
254+ (
255+ templatesPath = sourcePrefix + "app/views/" + subPath or
256+ templateFile .getRelativePath ( ) .matches ( sourcePrefix + "app/views/layouts/" + subPath + "%" )
257+ )
243258 )
244259}
0 commit comments