Integrated CMS Based Off Model for Rails - html

I have a site nearing structural completion. Essentially, it's made up of Users and Photos. However, Photos have a LOT of HABTM relationships, most of which are different kinds of tags, and others being categories, collections, etc...
My client would like to be able to have a conditional CMS based off the content being viewed for different promotional purposes or whatnot. For example, if a user is browsing the Category "Leprechauns", he may want to show html content about St. Patrick's Day or something. He may even want to easily include the browing user's name, if available. In which case, it'd be nice to have some sort of templating system. The part that makes this tricky is that these are small blocks of HTML for something like a 300x300 space in the sidebar and is NOT the primary content.
I've looked into refinery, but it seems to be too much of a complete solution. I've also thought about building in from scratch, but I don't know where to begin with treating dynamically generated pages (such as a new Category) as a recognizable object in Rails. I'd like to keep it more global than a slew of HABTM relationships, but it's looking like that might be where I'm heading. Ideally, he'd be able to make some HTML and check off "I'd like this to show on x and y Category page and b and z Collection page and for the tag Foo and for the tag bar as well as on my homepage"
Any suggestions? I'm open to finding a gem or getting a solid start on a homebrew.
UPDATE
I'm thinking of setting up some models Like the following:
cms_contents
============
id:integer
contents:text
timestamps
cms_associations
================
id:integer
cms_content_id:integer
model_id:integer
record_id:integer #optional
secondary_model_id:integer #optional
secondary_record_id:integer #optional
models
======
id:integer
name:string
Where:
cms_content would contain the HTML.
cms_associations would be an ActiveRecord model using has_many, :through
models would contain a the models the CMS content could be associated with
if record_id is not given, it associates with the model index
if record_id is given, it associated with the record of the provided model with that
id
if secondary information is given, a combination is created for other many to many
relationships
eg:
User has_many :photos
Browsing Photos for User(10)
model_id => #User model Id
record_id => 10
secondary_model_id => #Photo model id
So you could customize the content for browsing photos for specific users such as featured users or companies that may pay for advertising.
Any thoughts on this structure?

It's actually not that complicated. This is what you should do:
Introduce new object in the DB, name it htmlchunks
For every object that you'd want to associate with htmlchunks, create a join table and define habtm relationship
Modify your sidebar (for objects that have association with htmlchunks) in a way that they recognize whether there's htmlchunk associated with this particular object. For example, let's say you have a htmlchunk called "April Fools' Day" that contains simple html paragraph. In the sidebar, you'd just ask something like #category.htmlchunk? and output according to the result. You'd ideally place all this in a partial
As for creation of the htmlchunks you'd just offer simple wisiwig editor and ability to select any number of tags, categories, whatever. You'd create habtm entries between them and htmlchunks during the creation process
Let me know if you have further questions in the comments.

It's almost as if the almighty Ryan Bates is looking out for me, but the latest Railscast is on CopyCopter, which does exactly what I'm looking for, and runs as a separate app, so I don't have to worry about bogging down my main app. I suggest anyone who finds this to watch the screencast, as it seems pretty impressive.
http://railscasts.com/episodes/336-copycopter?autoplay=true

Related

Rails: create database structure for an archive

I have a general architectural question concerning the design of part of a database. I would like to implement an archive for an educational entity and have a form field, where I can query the archive and get a certain subset of entries. Everything started with only an archive of articles and lectures. I treated both as similar and used one table named resources with columns for all the data I needed in both cases. This way I could write in my Rails app something like:
Resources.find(:all).where('title LIKE ?', "%#{params[:searchTitle]}%")
and get all the resources with a certain string in its title.
Now I would like to extend the archive to comprehend a wider set of resources containing documentation of educational or research activities. I will have items as well as what you could call collections and sub collections. Items would be things like sheets, texts, images, magazines, books, music, video, drawings, models, maps. Collections would be something like courses, lectures, exercises, projects, exhibitions. A course can have multiple exercises and lectures. An exercise can have multiple projects, etc. But there might be projects without an exercise or course. I might choose to add keywords to the resources to describe content.
A query should result in a view with all related entries of single items and collections in one list.
I would usually create a table for each resource in order to have as few repeating data as possible. But I usually have one table as entry point for my queries and would have now 14 resources tables + join tables + tables such as authors. How should I set up the structure of such a database and in case I will have to create single tables for each resource: How do I query 14 tables and display the result in one list.
Thank you in advance.
in your controller action method,
resources1 = Resource1.where("title LIKE ?", "%#{params[:searchTitle]}%")
resources2 = Resource2.where("title LIKE ?", "%#{params[:searchTitle]}%")
resources3 = Resource3.where("title LIKE ?", "%#{params[:searchTitle]}%")
#total_results = resources1 + resources2 + resources3

Separate get request and database hit for each post to get like status

So I am trying to make a social network on Django. Like any other social network users get the option to like a post, and each of these likes are stored in a model that is different from the model used for posts that show up in the news feed. Now I have tried two choices to get the like status on the go.
1.Least database hits:
Make one sql query and get the like entry for every post id if they exist.Now I use a custom django template tag to see if the like entry for the current post exist in the Queryset by searching an array that contains like statuses of all posts.
This way I use the database to get all values and search for a particular value from the list using python.
2.Separate Database Query for each query:
Here i use the same custom template tag but rather that searching through a Queryset I use the mysql database for most of the heavy lifting.
I use model.objects.get() for each entry.
Which is a more efficient algorithm. Also I was planning on getting another database server, can this change the choice if network latency is only around 0.1 ms.
Is there anyway that I can get these like statuses on the go as boolean values along with all the posts in a single db query.
An example query for the first method can be like
Let post_list be the post QuerySet
models.likes.objects.filter(user=current_user,post__in = post_list)
This is not a direct answer to your question, but I hope it is useful nonetheless.
and each of these likes are stored in a model that is different from the model used for news feed
I think you have a design issue here. It is better if you create a model that describes a post, and then add a field users_that_liked_it as a many-to-many relationship to your user model. Then, you can do something like post.users_that_liked_it and get a query set of all users that liked your page.
In my eyes you should also avoid putting logic in templates as much as possible. They are simply not made for it. Logic belongs into the model class, or, if it is dependent on the page visited, in the view. (As a rule of thumb).
Lastly, if performance is your main worry, you probably shouldn't be using Django anyway. It is just not that fast. What Django gives you is the ability to write clean, concise code. This is much more important for a new project than performance. Ask yourself: How many (personal) projects fail because their performance is bad? And how many fail because the creator gets caught in messy code?
Here is my advice: Favor clarity over performance. Especially in a young project.

Flexible requests to database in Rails

I have the following problem in Rails which I am not sure how to solve. I build a test web application,a bulletin board with ads about real estate, like simple version of http://www.trulia.com/ and obviously users can add advertisements to the site which they can then find in their "office", and thats where the problem appears. I have 8 types of advertisements, like flats, offices, garages and etc, and so I need to be able to retrieve ads that belong to some particular user and I dont want to make sql requests to all 8 tables to show this user's advertisements, if user has , for example, just 1 ad about selling a flat.
So I need something instead of
#garages = Garage.where("user_id = #{current_user.id}")
#flats = Flat.where("user_id = #{current_user.id}")
#offices = Office.where("user_id = #{current_user.id}")
..... and so on
I have User model so all ads belong to some user and I am thinking of creating a polymorphic table which would belong to user and contained information about all ads the user invited
it would be named, for example,"Advertisement",it would have 3 columns, user_id, advertisable_id, advertiseble_type, and it would be very easy to get all rows that belong to some particular user, but I have no idea if its possible to make Rails get ads only from those tables that are in "advertisable_type" and with those ids from "advertisable_id", I hope you understand what I mean. So, any advices for a newbie? :)
If Your existing models Garage, Flat, Office are really advertisements, share a lot of same logic and columns, then obviously You need a data redesign.
If it's 99% the same thing why not just have Advertisement table and a column advertisement_type ? If You want a classifier for Advertisement type, simply use a separate table/model AdvertisementTypes and reference those by advertisement_type_id in Your advertisements table.
If You feel like there are/will be a lot of things in common, but there will be also a lots of distinct logic, it might be an ideal case for STI (Single table inheritance).
When using a STI You have different model classes which inherit from the same parent class and are stored in the same table.
class Advertisement < ActiveRecord::Base
def ad_text
"We are selling property: #{read_attribute(:ad_text)}"
end
end
class GarageAdvertisement < Advertisement
def ad_text
"We are selling garage: #{read_attribute(:ad_text)}"
end
end

CakePHP alternative to Class Table Inheritance?

I want to create a Class Table Inheritance model in CakePHP.
I would like to have a Model called something like ProductBase with the table product_bases to hold all the base information every product should have, like upc, price, etc.
Then have specific product type models extend that. For example ProductRing with the table product_rings to hold specific ring information like ring_size, center_stone, etc.
Then if I retrieve data directly from the ProductBase model, have it pull all types:
// pull all product types
$this->ProductBase->find('all');
Or find specific types only:
// pull only Rings or descendants of the Ring type.
$this->ProductRing->find('all');
Is anything like this possible in CakePHP? If not, what should I be doing instead?
What is the proper Cake way of doing something like this?
I worked with CakePHP for two years, and found no satisfactory solution for this, so one day I wrote a solution for it. I built a new kind of ORM that work as a plugin on top of CakePHP 2.x. I called it "Cream".
It works similar to the entities of CakePHP 3.0, but in addition supports multi table inheritance. It also supports very convenient data structure browsing (lazy loading) and is very easy to configure. In my opinion it is more powerful than what CakePHP 3.0 offers right now. Data structure browsing works as follows:
$entity = new Entity('SomeModel', $somePrimaryKeyValue);
$foo = $entity->RelatedModel()->YetAnotherRelatedModel()->someProperty();
However, it is important to notice, that in Cream, each entity object is a compund of a series of models and primary key values that are merged together. At least in the case where model inheritance is used. Such a compound looks like:
[<'SomeConcreteModel', primaryKeyValueA>, <'IntermediaryModel', primaryKeyValueB>, <'BaseModel', primaryKeyValueC>]
It is important to notice that you can pick up this entity by any of the given model/primaryKeyValue combinations. They all refer to the same entity.
Using this you can also solve your problem. You can use standard CakePHP find methods to find all primary key values you want from the base model, or you can use the find methods models that inherit from it, and then go along and create the entities.
You set up the chain of inheritance/extension by simply writing in your model class:
public $extends = 'YourBaseModel';
In addition you also needs to setup an ordinary CakePHP relationship between the models (hasOne or belongsTo). It works just like in normal OOP, with a chain of models that inherit from their bases. If you just use vanilla CakePHP you will just notice that these models are related, but when you start using the Cream interface, all entities merge model/primaryKeyValue pairs into one single object.
Within my github repository there is a powerpoint file that explain most of the basic features.
https://github.com/erobwen/Cream
Perhaps I should fork the CakePHP project and make a pull request, but for now It is a separate repository. Please feel free to comment or participate in developing "Cream".
Also, for those suggesting that it is best to just "work with the CakePHP flow as intended" I would argue the following. Common estimates suggest that C programs are 2.5 times bigger than the C++ counterpart. Given that the only feature that separates these languages is the OOP with inheritance etc, we can deduce that the lack of proper OOP with inheritance etc requires the programmer to do 150% additional work with repetition code etc. Therefore I would argue that a proper model inheritance mechanism in CakePHP is very much needed. Cream is an attempt at this.
You are referring to an ARC relationship (or at least a variation of it). Cake does not handle these types of relationships on the fly. This means you will have to implement your own logic to handle this.
The other option is to categorize the products. If the product can fit into multiple categories, then you will want a HABTM categories for each product. Otherwise, you can use a category column. I suspect it will be a HABTM you are looking for.
PRODUCTS: The table that holds the
products.
CATEGORIES: The list of categories
any given product can belong to.
CATEGORIES_PRODUCTS: The link between
each product and their various
categories.
TYPE: This is the flag that will
define the type of product (i.e.
ring, shoe, pants, etc.)
Then when you want ALL products, you query the products table. When you want a slice of the products (i.e. Rings) you select all the products that belongs to the RING category.
Now, we need to address the information about the product. For example, not all information will apply to every product. There are a number of ways to do this.
You can build multiple tables to
hold the product information. When
you pull a product of a given type,
you pull its companion information
from the table.
Store the information in a text
field as serialized data. All of the
information can be defined in a
settings var and then you can use
the serialized data to map to the
information.
I hope this helps. Happy coding!

In web development, what are "term", "taxonomy terms" and "vocabulary"?

I need to create 2 more tables with purpose: one table will store tags and categories data (categories can have a hierarchy but tags are not) and another table store relationship between tag, category and content. But I so confused about name of those 2 tables. I'm really a newbie in web development. After googling a bit, I found some words like term, taxonomy terms and vocabulary from drupal and wordpress. But I have no idea what they mean. Can you explain those words and help me give a name for my two tables. Of course if those tables are not well design for my purpose please guide me too.
content{
content_id
...
}
table_A{
type (tag, category, ...)
name
parent_id
}
table_B{
table_A_id
content_id
}
With relevance to wordpress, those words are indeed confusing. If you are using wordpress to build a site, you shouldn't need to worry about the database tables for storing taxonomies and terms as it has built in methods to handle all that.
You'll notice when you're in the wordpress admin panel editing a page or post that there is by default a box on the right which calls itself "Categories" and allows you to create new categories. Once one is created, you can add your posts or pages to any "Categories" you've created. I'm sure you understand that already.
As wordpress releases were built, people started asking for more customizing control over categorizing their content. So developers added "custom taxonomies" to wordpress. For clarity, I should mention that "Categories" is the name of a default "Taxonomy" built into wordpress.
A taxonomy is a group of terms. So when you create a "Category" in the right hand box of the admin panel (say "news" for example), you are creating a "term" named "news" which belongs to the "Categories" taxonomy.
This allows a developer to define their own taxonomy (let's say "products") and associate it with pages, posts or any other "post type". So if it's associated with just plain regular "posts" in the admin panel. A box exactly like the existing "categories" box would show up upoon editing but would call itself "products" instead. Anything added to that list would be a term under the "products" taxonomy.
Hope this clarifies things a bit for using wordpress. These terms can be used differently in different contexts so nothing I've said necessarily applies to anything outside of the wordpress package. Unfortunately there is often no universal "web development" meaning for a given word you may see thrown around in discussion.
Taxonomy, last time ago, means categorize life organisms. Similarly, in computer engineering, taxonomy means categorize terms, can be substantive(three, car, cat), verbs(go, be, do). Taxonomy and terms can be mens anything, but the concept is a data structure and hierarchy