This is more of an application design question then a specific Rails question. I'm trying to implement a system like "labels" within Gmail. So I want a user to be able to apply a label (or many) to a specific post. However, I also want the user to be able to manage labels using standard Rails CRUD.
Let's say I have a model called Post. So a user has many Posts. A user can create labels which is a separate model from Posts, but these can also be applied to posts with the use of checkboxes in the Post new/edit views. If a user deletes a specific label, it simply gets removed from the Post view and doesn't affect the Post in any other way.
This situation shows my lack of knowledge of db relationships, but is this a case for a has_many_and_belongs_to_many relationship?
If so, would the following design be the way to implement this?
User has_many Posts
User has_many Labels
Post has_many_and_belongs_to_many
Labels
Label has_many_and_belongs_to_many
Posts
Maybe I'm over thinking this and my logic is way off.
You have to decide whether or not you want tags to be "owned" by people or just "used" by people. In gmail, my labels are very specific to me. In SO the tags are not specific to me even though I can create them.
If you want labels as opposed to tags then yes.
User ---< Label
Label >--< Post
User ---< Post
You can define these in English if you want.
A user has zero, one or more Labels
A Label is used by one and only one user
A user has zero, one or more posts
A post is created by one and only one user
A post has zero, one or more labels
a label is applied to zero, one or more posts
I wouldn't say you've over-thought this CONCEPTUAL data model.
From your question, it seems like you are trying to build a taxonomy system (i.e. tagging model). You may want to check out Acts As Taggable On as a possible solution (or just an interesting modeling reference) for your problem.
It sounds like you could implement this functionality through tags. Check out this post for a list of tagging plugins and gems for rails.
Related
I am using three models:
- users
- events
- user_events (the join table)
I feel like I do not need to save every search result because it would be unnecessary. The search will query two APIs and display maybe the top 10 results and display them to the user. The user then might be interested in one or two of these events and add them to a list of things that interest them, a bookmark, if you may. Bookmarks that are happening on the same day should then be grouped together for the users organizational purposes.
Should I make another search model along with a search controller? I'm fairly new to Rails and need some advice on this topic.
I would advise you make a bookmark or search class to store a search when a user wants to save it. Then you can construct a has_many relationship between a user and a bookmark. So a user will have many bookmarks. See this for more documentation: http://guides.rubyonrails.org/association_basics.html#the-has-many-association
I'm writing an app that allows users to feed their inbox, then process their input, making it either a note or a task.
Since I need notes and tasks to behave very differently, I plan on using different models for them.
The question is: how do I go about changing inbox items into notes or tasks?
My first idea was to write an action that would destroy an inbox item and call the create action on the notes (or tasks) controller, but that does not seem right.
Is there a better way to do this?
Update
I'm looking into polymorphic associations as a solution for this, as suggested by #Dipak.
This is my schema: (sorry I can't paste the code. I'm using a web based ssh tool)
I have decided to use the Idea model to define inbox items
And these are my models:
I want to be able to click this link (on my partial)
and have it do two things:
create a task
assign this task to idea.thought
How should I do this? Is this the proper way to use this kind of association?
As per your question it seems like your few initial fields are same for all notes and tasks, that you calling inbox. So better you can save those fields in different table and other fields in related table.
For such situation you should use polymorphic association. You can read about it here. So your new inbox table should be intermediate table used for polymorphic association.
First of all, I want to apologize for my terminology. I am not entirely sure what to call what I am looking for, so I can’t google for answers. But here is my problem.
I am working on a Rails application that stores information about different websites and provides various services for them. I will call these services ‘Products.’ One website can be subscribed to several products, and a product can be served to various websites. So here is a very simple association scheme for these relationships:
At least, it would have been simple, but the problem is that the Settings model (shown in red on this diagram) is different for each product: for one product, it will have one number of fields and data types, for another it will have a different number of fields with different data types. On the other hand, the Faq and Description are the same, so if I redraw the diagram as follows:
I will get another problem: too much repetition (shown in blue on the diagram). Ideally, I want some kind of modification of the first diagram, where the Product model will choose differens Settings models depending on a parameter that I pass to it:
So that a request website.products.find(1).settings will return the model Settings1, while a request website.products.find(2).settings will return a completely different model, Settings2.
Is this achievable in Rails? If not, how would you organize such data?
I'm learning Rails by building a simple site where users can create articles and comment on those articles. I have a view which lists a user's most recent articles and comments. Now I'd like to add user 'profiles' where users can enter information like their location, age and a short biography. I'm wondering if this profile should be a separate model/resource (I already have quite a lot of fields in my user model because I'm using Authlogic and most of it's optional fields).
What are the pros and cons of using a separate resource?
I'd recommend keeping profile columns in the User model for clarity and simplicity. If you find that you're only using certain fields, only select the columns you need using :select.
If you later find that you need a separate table for some reason (e.g. one user can have multiple profiles) it shouldn't be a lot of work to split them out.
I've made the mistake of having two tables and it didn't buy me anything but additional complexity.
Pros: It simplifies each model
Cons: Managing 2 at once is slightly harder
It basically comes down to how big the user and profile are. If the user is 5 fields, and the profile 3, there is no point. But if the user is 12 fields, and the profile 20, then you definitely should.
I think you'd be best served putting in a separate model. Think about how the models correspond to database tables, and then how you read those for the various use cases your app supports.
If a user only dips in to his actual profile once in a while but the User model is accessed frequently, you should definitely make it a separate object with a one-to-one relationship. If the profile data is needed every time the User data is needed, you might want to stick them in the same table.
Maybe the location is needed every time you display the user (say on a comment they left), but the biography should be a different model? You'll have to figure out the right breakdown, but the general rule is to structure things so you don't have to pull data that isn't being used right away.
A user "owns" various resources on your site, such as comments, etc. If you separate the profile from the user then it's just one more resource. The user is static, while the profile will change from time to time.
Separating it out would also allow you to easily maintain a profile history.
I would keep it separate. Not all your users would want to fill out a profile, so those would be empty fields sitting in your user table. It also means you can change the profile fields without changing any of the logic of your user model.
Depends on the width of the existing user table. Databases typically havea limit to the number of bytes a recird can contain. I fyou are close to (or over which you can usually do if you have lots of fields with null values) the limit, I would add a table with a one-to-one relationship for better performance and less of a likelihood of a record that suddenly can't be inserted as there is too much data for the row size. If you are nowhere near the limit, the add to the exisiting table.
I have a Comment model in my app but am encountering a lot of problematic postings that I have to remove manually.
What I want to do is add a "flag for moderator attention" feature so that users of the app have the ability to remove a comment from view without my need to review all content in the app.
I'm thinking that after a comment has been flagged three times, I will remove it from view automatically and then when I have a chance to review these postings I will decide whether to allow them or permanently remove them from view.
What I'm having trouble with is how to implement this.
Should I have a separate table that records all items that have been flagged?
Or should I have a "flag count" field as part of the Comment table that keeps track of how many times a comment has been flagged?
A separate table would allow me to keep track of detailed information about the flagging actions - who is flagging, which IP they are flagging from, etc. This is what I'm leaning towards.
But perhaps a gem or plugin already exists that does this type of thing?
I don't know of any plugin. I like the solution you are leaning towards.
If you want to hide the comment after three flaggings have been created for it, you need to keep track of who created them, so people can flag just once.
I'd create a flag resource (which can hold any kind of flags your users can assign to particular comment), then a flagging resource which connects flags with comments and holds information about the entity which is responsible for flagging (which could be a user or a user represented by IP).
Every comment will then have many flaggings.
You can use state machine to change the status of a comment to "to_be_revised" or something similar after three flaggings have been added. State machine (aasm_state_machine or the one which is now incorporated directly into Rails) will also provide you with named_scopes for groups of comments with the same state.
After revision, you can set the state to "published" again and delete all the flaggings or to "unpublishable" and so hide it forever.
Perhaps the acts-as-flaggable plugin would work.