RAILS 3.2 - Nested resources has many : through relationship - ruby-on-rails

Guys I am becoming completely nut on this...and can't figure out at all how come out of all this troubles.
I really need an holy help, or at least some suggestions about tutorial and guides about this problematic.
I believe that this is a very common task in many app, but I can't find nothing that help in this sense, not on stackoverflow, not on google, not on other rails forums that I know...I start to feel like a dumb!!!
Problem
(1) Models (the models that are involved)
User.rb
Item.rb (is nested in user: e.g. user/3/item/5)
(2) What I'd like to do
The current_user (the user that is logged in) can create an Item, and in the same form can decide to share it or no with many other users.
In this way, the item will be visible and accessible also for this users that we shared it with.
I understand that what is going to be involved here is:
(a) has_many :through relationship between item and user
(b) a joint table that we can call sharing (with item_id and user_id)
(c) eventually using different name for the user and use a :class_name to point to user
This is not hard to implement (and there are plenty of examples around).
What is really a mess, instead, is how build the controller (item controller), in order to perform in one shot, the creation of a new item, and the sharing operation (this means setting up the parameter in the joint table, and eventually create as many records as many users we are sharing with - array?)
And the other problem, that obviously is related with the controller, will be the view...how put all this in a single form, and allow the current_user to just click the button, and perform the item creation + the sharing operation?
Last thing, but not the least, how I need to deal with the fact that User is the same model of current_user??
I really don't know what I need to read or look up in order to let this work, I would love to see some example code,but at the same time I'd love to really understand the logic in all this, in order to be able to replicate it in other scenarios.
Please someone help me...I can't really move on in my app development without doing this, and this is also a crucial part of all the project.
Thanks so much for every small bit of help that I will receive.

Ok I have solved all my problems...that was not an hard task at the end (it's always easy saying that when you solved the issue:))
The only doubt that I still have is with the rails name convention:
Can be possible that using a name like sharing, for the joint model, that the final -ing is not very well handled by rails?
After many tentativeness performed to try to fix my problem, I discovered that everything was set up properly, and that just changing the joint table name from sharing to share, let the magic works!!!

Related

How can I give all users access to a read-only ‘sample’ in Ruby on Rails?

I'm working on fairly standard Ruby on Rails app where users have many studies. When a user signs up, I would like them to have a sample study as an example, similar to how Trello gives you a sample board on sign up.
My current approach is to deep_clone Study.first on registration and assign ownership to the current user. This means new users can edit their clone of the sample study and no-one else can see their changes. This works fairly well however it has now become quite complicated to clone studies as my associations are a lot more complex.
To simplify, I would like to change my approach for the sample study. Instead of cloning, I now want to give everyone access to the first study in the database, but read-only. Studies have a few views, e.g. users can change questions, participants, settings, add tags, etc. They should be able to see existing questions, participants, settings, and tags, but not add, remove, or edit them for this sample study.
I believe I need to:
Figure out how to make Study.first show up for everyone in all the right views without it actually being owned by current_user
Make this study read-only for everyone except me
What's a good approach for doing this in Rails?
For a classical server side application there are few ways around that you would need to use some sort of persistence to store the users changes between requests.
You could possibly setup some sort of inheritance so that studies can inherit from another study and use delegation to avoid duplication.
class Study
belongs_to :master, class: 'Study', optional: true
def get_some_field
master ? master.get_some_field : super
end
end
If the user is manipulating questions, participants, settings, and tags they should merely be working on join tables which are pretty cheap since they only involve storing two integers per row.
Another solution could be storing diffs or just the actual changes the user performs. It might be possible to use paper_trail or at least study it as a starting point.
For an ajax heavy application or SPA you might want to use local storage to fake the whole server interaction.
When a user creates a demo study they would fetch /studies/1.json and then when the play around they are just manipulating the object stored on the client.
In Ember you could for example swap out the adapter to ember-localstorage-adapter.

Ruby on Rails: Should a single field ever get its own model?

I'm new to Ruby on Rails. I have a relatively simple question. I'm modeling users. I want users to be able to have a short "profile message" that they can edit and that gets displayed on their profiles. Would it make sense to make ProfileMessage its own model? Or, should profile_message be one column in a table that contains user settings?
I feel like an entire model just for one string is a little bit overkill and if I start going that route, I'm going to end up with so many models that things become cumbersome.
What does the community think?
I would keep your data structure as simple as possible when starting out. For a profile message, it doesn't make much sense to have it be it's own model. Only if profile_message were to later on have it's own set of attributes and behaviors, or if users could have more than one profile message...then I would consider moving it to a separate model.
Table joins in SQL consumes a lot of resources when you are not using them properly. In your case i think that making a new model only for the one profile_message is not a good practice.However, it should be implemented inside the user/profile model.
This approach is going to make accessing the message faster, on the other hand if you are using a whole table for the profile_message will make the response time slower because you will need to look for it every time in the profileMessages table which will take more time depending on the number of entries in that table.

not sure whether to create new models

I'm making an app with Rails that, among other things, allows certain types of professionals to create an online profile. So there is an 'association' between the User and Profile model. I created the Profile model so that I can basically restrict the User model to name and registration information, and keep profile information elsewhere (i.e. 'normalize' the db as I think it's called)
However, these profiles (as is often the case, on LinkedIn, for example) contain a lot of information. For example, there will be a section for Work Experience that sometimes looks like this, where a user can add many different work experiences.
and then something similar for education
And many other different types profile information. Note also, that the ability to add to and edit these discrete categories takes place in separate forms. I can add to my work experience without touching education.
My question is, should I try to store all of this information in my Profile model? Or, would you, for example, create a WorkExperience model and do something like Profile :has_many work_experiences? and something similar with EducationExperience, or is there even another way to do it?
One of my concerns is queries on the DB. For example, in terms of performance, is there going to be much of a difference if, in the show action of the Profile controller, I do queries for WorkExperience.all, Education.all rather than storing all the information in the Profile model?. Another concern is just general code organization for profiles that can become quite large.
You'll have the cleanest code (and decent performance) by splitting out something like Experience (which will belong_to Profile), along with a type column that determines whether it's "work" experience, "education" experience, etc. That's the approach I would take, unless the different types of experience have vastly different columns.

Design question in Ruby on Rails

Ok the scenario is simple(?). I have say Articles, Reviews and Comments, three different models that a user can update. I was wondering what is the best design to follow if I want the updated records (from the user) to become available only to an administrator (and not in a public view) but at the same time the old ones remain as is until the admin reviews them.
First thought was that would be best to have self-referential joins, making a new record on the update action of the user and referencing the old one so that the admin when finishing the review the old record, the latter gets deleted and the reviewed one gets published. I seriously think that if there are many updates from users, then the table holding the data will grow BIG in a very short time. Do you have any other suggestion?
Thank a lot for the help :)
P.S. I am using Ruby on Rails framework, if that makes any different at all..
This kinda reminds me of Wordpress draft system and to be sincere, i think it's probably one of the few ways to do it. That is, have a column with post_type like [draft,published etc..]. Alternatively, you could have a drafts model alone and a published model that are polymorphic of the Article model. I think that you are right in your concerns about a table getting too big. Thus, i think that you would better choose a strategy of removing old drafts or archiving them in another table, so that they just occupy space and not mess with your search time for them (also, remember to use indexes for better performance).
Maybe act-as-state-machine can help as well ( http://www.practicalecommerce.com/blogs/post/122-Rails-Acts-As-State-Machine-Plugin )
One thing to keep in mind is that unless you're trying to create a detailed revision history, there are really only two versions of a given article, view or comment that you need to keep around: The current approved public version of the item and the current edited version of the item. So you can probably just story two copies, and copy the draft version into published and delete the draft when it's approved, or update it if the user makes additional changes before it's approved.

Ruby on Rails - Create Entity with Relationship

I'm new to rails, so be nice.
I'm building a "rolodex" type application, and this question is about the best way to handle creating an entity along with several relationship entities at the same time.
For (a contrived) example:
My application will have a Person model, which has_one Contact_Info model. On the create.html.erb page for Person it makes sense for the user of my appliction to create the person, and the contact_info at the same time.
It doesn't seem right to include details for creating a contact directly in the create view/controller for person. What's the rails way to handle this?
Using nested attributes is the most common way to do this.
The actual documentation is here.
You want to use "Nested Forms". There is a great example of them in this blog post.
I'm also noob, but I had a similar issue with an app. I was using a tutor at the time and he basically said it was a good example of rails being opinionated. It sounds like you want to take the create action for two different models at the same time, which may be possible but probably very hard. Id suggest considering whether your data model could be modified, or find a way to make an acceptable user flow while collecting the data in different forms.
Update: while writing this the technical answer came in. Keep in mind, its perfectly okay to take the easy route if doing so helps you get the app out the door, and especially while you're still new.

Resources