I'm wondering what the best design for the following would look like in Rails:
A website with three different image galleries, let's say one showing pictures of the company's staff under mywebsite.com/gallery, another one shows pictures of product A at mywebsite.com/productA and the third shows product B under mywebsite.com/productB.
I assume it would be bad design to create a gallery resource, along with a productA and a productB resource since there will be only one of each and it's really the new photos and not new image collections which will have to be created.
So I'm thinking if it's a good idea to create an images resource and then use single table inheritance, instantiate a gallery_images, productA_images and productB_images and change the routes to the respective ones which I want to show up as URLs. I should probably mention that I don't want to mix up the images for the different sections.
I feel there must be a "proper" way of doing this, I guess tons of websites use a similar scheme.
Not to say that this is a "Rails way", but I've seen it done as follows in most of the Rails projects I had access to. Basically, when it comes to galleries, you would want to let customer upload and manage the images. So, you would use gems like paperclip and carrierwave. Once you choose one of these gems, your class design is predefined. You'd have a model that has an attachment.
Then, you would simply initialize a specific instance of your model (or a model with has-many attachment model association) and simply render a list of image URLs in your HTML template. The actual gallery is then styled and brought to live on frontend using CSS and JS.
As for the difference between other contexts. Let's say OOP. If you are looking for the "correct" way of doing it in OOP context, you would first have to consider your business domain. And design your classes so that they reflect your business requirements (taking into account all OOP principles). A best way to start this journey would possibly be learning and understanding OOP principles and forgetting that "Circle extends Shape, Rectangle extends Shape and this is what OOP is!" kind of mentality. Design patterns are actually a good example of what you end up with if you follow OOP principles. Head First DP is a good introductory book.
Related
I would like to create a blog with an Ember front-end, a Rails API acting as the back-end and and AWS to store the images. I was thinking of dividing up the posts into objects: paragraph, image, etc... and storing them in a relational database (postgres). This would then allow me to generate the corresponding Ember components on the front-end depending on the model i.e. render a paragraph component for each paragraph, an image component for each image, etc. I figured this would allow me greater flexibility when displaying the posts The end goal would be to also create the CMS to manage the blog. Is this the right way to go about this?
Is this the right way to go about this?
Your approach is good. A solution should depend on flexibility need when it comes to displaying, manipulating these paragraphs, images etc. If only CSS styling isn't sufficient then sure, you can go with storing each paragraph, image as a separate entity in the database. It should be very easy on Ember side to work with such API.
You can do as you said : a document is a set/group of entities (images, paragraph,...) or you can keep it simple : store the content of the blog post in a specific syntax (example: markdown) and when display you can prefix image to AWS.
For sure the more, you divide the more you are flexible, but you will need to have more relation between entities
User should be able to send some pictures to his chat partner (whatsapp/line style).
There might be a possibility to also add other attachments and videos. We having an argue about the model structure. We are using carrierwave to manage the files. right now, the user can only send Pictures, in future there might be some other datatypes to be added.
Solution 1
pretty standard imo, having 3 classes (each has own DB table) and each class is getting his own carrierwave-uploader.
Chat::Picture
Chat::Video
Chat::PDF
Solution 2
this might be a little bit more trickier. Instead of 3 Models we are only having a Chat::Attachment and by that we use STI to define the type.
Chat::Attachment::Picture < Chat::Attachment
Chat::Attachment::Video < Chat::Attachment
Chat::Attachment::Pdf < Chat::Attachment
here also every class is getting his own uploader.
So the Question:: is this the right spot to use STI as a design pattern or should we stick to regular rails-models?
The answer depends on how much change you expect in future. If you expect more changes in future then you should go for rails usual way. I personally dont like STI much. I think you will be better off not using STI here, rails will provide you better separation of concern here. STI should be considered when dealing with model classes that share much of the same functionality and data fields, but you as the developer may want more granular control over extending or adding to each class individually. Rather than duplicate the code over and over for multiple tables (and not being DRY) or forego the flexibility of adding idiosyncratic functionality or methods, STI permits you to use keep your data in a single table while writing specialized functionality.
I'm developing a site with Ruby on Rails. I have data on layout that doesn't repeat more then once. And I need to enable content-menegers to change it easily. I could create a model or several models for them and let content-managers edit it in RailsAdmin. But I doubt I should use models that way because entities of such models will be ment to exist in singular number. I mean there aren't multple site names, logos, backgrounds, welcoming texts, etc. But I want to enable them to be edited in a web-interface or equally comfortable not worrying about the cache and not looking at code and serfing through complicated directories structure.
What is the right way to do that?
Possibly a fairly basic question, but bear with me.
I'm building a page which has a number of pieces of modular content, represented by a ContentBlock model. Each ContentBlock has at least one link, each of which has a couple of different attributes. My initial approach was to just add these links as an array to the model, as there didn't seem to be any real need to store them separately in the database, and they don't have any logic of their own. Now that I'm looking at building a form for creating/editing a ContentBlock though, it seems like it would be much easier to build if there was a separate, nested model for the links.
I'm strongly considering converting to using a model, but my gut feeling is that it's kind of "wrong" to store something like as relatively trivial as the links are in the DB. Given I am still getting used to working with Rails, is this feeling misplaced? Should I just create models for anything and everything? Or should I be looking for some sort of minimum criteria before I do?
It is definitely easier to create forms for nested models. Since your links have attributes, I'd suggest making a model. I tend to err on the side of making models for concepts that can't easily fit into fields. If you're worried about query performance, you can always do eager loading.
I think depends on how much data you plan on managing, what you want to do against that data, what that data represents, etc...
One project we had was to build something that allowed creation of recipes for a group of restaurants. Recipe (some text, like instructions, etc...) -> Ingredient, we went with an array, as these were all single lined text and there would never be more than several hand fulls. Also, the ingredients had no further dependencies. The Recipes would only be rendered out to html and there would be no searching against them (not against the db at least).
Another project required building a Page, very similar to yours, but each "component" of the page did different things and some where linked to other objects in the app, like Videos and other assets, templates, etc... We had seen people do this type of stuff entire through a wysiwyg or through some JS way and saved the entire payload/structure in the DB. We found both to be extremely messy.
And one concern that came up was what happened if an asset/associated object was mistakenly or purposely deleted but lived throughout many pages. Using models allowed to ensure that if something got removed, it got removed within all it's linked associations (though this posed problems of it's own, but more regarding the page making sense when displayed more than anything else).
Also, our Page had the potential of becoming extremely large with different types of components with different looks and inter-activities, that this really was the only way we could properly manage it.
So I would look at your requirements and plan accordingly, context matters. And if you have to change it (which happens, a lot) then you'll change it.
My site, Rap Genius, explains rap lyrics. I want to create a new site, Rock Genius, that explains rock lyrics – otherwise it'll be the same (same layout, same DB schema; like Serverfault is to Stackoverflow)
What's the best way to do this?
Approach 1: Fork the code
Fork the Rap Genius code, change the relevant parts (e.g., "Rap" -> "Rock"), create a new database and go to town.
Pros: Can get it working quickly
Cons: It'll be somewhat painful to add a feature to both applications. Also it'll be impossible to give Rap Genius access to Rock Genius' data at the DB level
Approach 2: Keep it a single application
Whenever a request comes into my application, check the domain. If it's rapgenius.com, set the SITE_NAME constant to "rapgenius". Create a genre field on user-facing entities (songs, blog posts, etc) and update my queries to use the correct genre based on the SITE_NAME
Create a layer of abstraction above user-facing strings to that I can write <%= welcome_message %> instead of Welcome to Rap Genius! and have welcome_message() take SITE_NAME into account
Pros: Lots of flexibility
Cons: Lots of work!
Thoughts?
The second approach sounds better to me.
You've already highlighted the main pros and cons - it will definitely be more work, but will be much friendlier to maintain. Is there any chance of a third, fourth, fifth site? If so, there's no question that this is the right way to go.
You'll likely also be able to share user accounts, reputation, and any other kind of community based functionality more easily.
It might be worth looking at Rails i18n stuff for 'translating' static text, based on the domain name. That way you could avoid writing helper methods for every string you want to display.
Then you should be able to 'franchise' the site really easily - add translations of static strings, a handle for the new domain, and maybe some site specific images or CSS and you're done!