Show selected image in new view

In new view I select an image which has already been stored in Active Storage (I’m selected from a drop down list of images), but I want to have it appear so I can draw a rectangle on it. The rectangle will be a portion of the image (“snippet”) which will be visible in the show view.

How do I show the just selected image in new? Is there a Rails solution? Stimulus seems like a possibility, but I haven’t used it. After reading an introductory tutorial on Stimulus, it may be easier to tackle it via JavaScript.

Other background:

Snippet will be show with <%= image_tag(@location.doc.image.variant(crop: '350x40+650+230')) %>. I’m planning to get the crop info using OpenLayers Draw createBox and store the width-height-top-left-coordinates with the record.

The images are pages from City Directories from around 1900 (like phone books—or is everyone here too young to know what they look like) and the snippet will be one to around six entries, so a small portion of the whole page. Usually I use one entry from a page, but sometimes several scattered around the page. The full images are around 2000 x 3000 pixels and the snippet will be less than ¼ the overall width and around 1/50 the height.

I’m only marginally competent at all this. I’m learning as I go.

Thank you for any pointers.

If you want to select the image in one view, and then move to cropping it in a different view, that would be one way to approach this. What I dimly perceive you may be asking is how can I choose the image in the picker, and have the croppable preview appear on the same page, without a round-trip. For that, I would use Stimulus or UJS. You’d want to take the value from your picker, and use it to create the Ajax request that will load your image into the cropping “stage”. The two options are really a lot closer to one another than you might think, though. The best advice I can give you about Ajaxifying a page is to make it work without Ajax first, then layer on the gloss finish.

So if you had an Image#index method to show all the possible images you wanted to choose from, and then clicking one of the images would move to either an Image#edit or maybe (more RESTful) a Crop#new method, that would be the old-school full round-trip way to structure this. Crop#create would save the cropping parameters along with the image ID, and from that you could construct your cropped image for display later.

You can use Ajax to collapse the display of these routes into something that appears to be all in one page, when under the hood, it’s just exercising the same routes as the full-round-trip method.

Does this help at all?


Thank you, it helps. And yes you understand what I’m trying to do. To clarify, I can live without the cropped view being shown, but do want to load the image to crop it. As I said I’m not very competent at this, but I think I can work my way through it. One of the complications is in one model, new is also creating locations on a map, so I have JavaScript (OpenLayers) working on the page at the same time. I’m starting on one that doesn’t involve OpenLayers though to work my through it.

I think your second paragraph may be suggesting that I create a record of the cropped image for use elsewhere. I thought of doing that but it’s probably easier to just create the crop at the time I create the record and non reuse it (even though I may have the same crop in several places).

But I still need to work through your suggestions. I’m also tackling how to create the crop in OpenLayers, although I think I have the pieces to do that. I’m working on this now. I think this fits with your suggestion to do it without AJAX to begin with.

Thank you for the suggestions.

Sounds good. Don’t forget that you can have LOTS of controllers. There’s no need to have a particular controller handle everything about the same-named model. That’s a convention, but it’s not the only way to go. If you think about the crop activity as being separate from creating the image, then a CropsController could be acting on an Image. Think about it from the REST perspective – you’re exposing a property as an action.

Also, I was thinking about your images perhaps containing more than one crop apiece, and each one might want to be addressed separately, for example if you have a map, and three counties shown in one map, each county might relate to a different crop taken from the same map image.


Thank you for the advice. Got it working. One cop out was to simplify new by just putting in a few fields and selecting the image, then redirecting to edit where I implemented the snippet drawing. Took me a while to get the pieces together and one post at Stackoverflow dealing with how to handle the coordinates. Have two OpenLayers scripts which still need some sorting out.