3

I'm using the Yesod scaffolded site (yesod 1.1.9.2) and spent a few hours yesterday wrapping my head around basic usage of Fay with Yesod. I think I now understand the intended workflow for using Fay to add a chunk of AJAX functionality to a page (I'm going to be a little pedantic here just because someone else might find the step-by-step helpful):

  • Add a data constructor Example a to SharedTypes.Command.
  • In the expression case readFromFay Command of ... in Handler.Fay.onCommand, add a case that matches on my new data constructor.
  • Create a Fay file 'Example.hs' in /fay, patterned after fay/Home.hs. Somewhere in here, use the expression call (Example "foo") $ myFayCallback.
  • Define a route and handler for the page that will use the Javascript I'm generating. In the handler, use $(fayFile' (ConE 'ScriptR) "Example.hs").

My question: In the current Yesod/Fay architecture, how should I go about sharing my Persistent model types with my Fay code?

Using import Model in a Fay file doesn't work -- when I try to load the page that's using this Fay file, I get an error in the browser (Fay's standard way of alerting me to errors, I guess) indicating that it couldn't find module 'Model' but that it only searched the following directories:

  • projectroot/cabal-dev//share/fay-0.14.2.0/src
  • projectroot/cabal-dev/share/fay-base-0.14.2.0/src
  • projectroot/cabal-dev/share/fay-base-0.14.2.0
  • projectroot/fay
  • projectroot/fay-shared

I also tried importing and re-exporting Model in SharedTypes.hs, but that produced the same error.

Is there a way to do this? If not, why not? (I'm a relative noob in both Haskell and Yesod, so the answer to the "why not?" question would be really helpful.)

EDIT:

I just realized that mentioning Persistent in this question's title might be misleading. To be clearer about what I'm trying to do: I just want to be able to represent data in my Fay code using the same datatypes Yesod defines for my models. E.g. if I define a model thusly in config/models...

Foo
    bar BarId
    textThatCanBeNull Text Maybe
    deriving Show

... I want to be able to define an AJAX 'command' that receives and/or returns a value of type Foo and have my Fay code deal in Foos without me having to write any de/serialization code. I understand that I won't be able to use any of Persistent's query functionality directly from my Fay code; I only mentioned Persistent in the title because I mentally associate everything in Model.hs and config/models with Persistent.

Christian Brink
  • 663
  • 4
  • 18

1 Answers1

3

This currently is not supported; there are many features leveraged by Persistent which Fay does not support (e.g., Template Haskell). For now, it probably makes sense to have an intermediate data type which is shared by both Fay and Yesod and convert your Persistent data to/from that type.

Michael Snoyman
  • 31,100
  • 3
  • 48
  • 77
  • Bummer, but thank you for answering! Do you think it at all likely that Fay will be extended in the nearish future (say, 6-12 months) so that it supports the relevant Haskell features? And/or do you have any plans to adapt Persistent so that our model types (or even some useful subset of the many types Persistent generates for each model) can be used in Fay code despite Fay's limited language feature support? I noticed that 'postgres-fay' is now an option in the `yesod init` script; seems like you must be cooking **something** up... Or am I misinterpreting that? – Christian Brink Mar 31 '13 at 16:51
  • 1
    There *are* plans to make it easier to use Yesod+Fay, but nothing in this specific direction. I actually use Fay extensively in fpcomplete.com, but mostly follow the advice I give here. It actually works out very well in practice most of the time, as there's usually some data in the model that you wouldn't want the client to have access to. – Michael Snoyman Apr 01 '13 at 18:18
  • I agree with @MichaelSnoyman, a separate type usually makes sense. But of course it would be nice to be able to share these types as well to speed up prototyping. We are currently looking into migrating Fay to either the full haskell-suite or the GHC API. We have done about as much as we can using haskell-src-exts at this point. If we pick the haskell-suite it will depend on when they are ready for release, I'm going to talk to Roman about their progress this weekend. Either way, I'm not sure if it will be possible to just use the persistent models in Fay, we'll revisit this later! – Adam Bergmark Apr 30 '13 at 05:11
  • Thanks Adam. It feels very helpful to have that extra insight into the direction this is taking. – Christian Brink May 01 '13 at 00:50