Ruby on Rails 3 multiple tables - ruby-on-rails-3

This is my first ROR application, so this is probably a basic question. I'm building a review site where users submit reviews.
I have a User model, a Review model, a Location model, and a Category model. The Category model belongs to the Location model, and I have that the Review model belongs to the User model. User has many reviews and Locations has many categories.
So when a user navigates the site they see a directory of locations (~/locations), clicks on a link to a location, which then displays the Categories for that locations (~/locations/:id/categories). When the user clicks on a category (~/locations/:id/categories/:id) I have a new review link on the page which sends the user to a form to create a new review (~/users/:id/reviews/new).
The problem I'm having is how do I send the category_id and location_id along with the user's review. I need the additional ids to show the reviews for the correct category, As of now, the user goes to ~/users/:id/reviews/new to create their review, which allows me to easily grab the user_id. How do I also get the category_id and location_id?
Any input is appreciated.

If the link is on a page where you have both the category and location, one option would be to pass them as query strings by creating your link with something like this:
<%= link_to "New Review", new_user_review_path(#user, :category_id => #category.id, :location_id => #location.id) %>
Then they are available in params
params[:category_id]

Related

Rails query in controller with multiple conditions

I have the following relationships set up in my models for Festivals, Categories, Submissions and Curators (users).
Festival has many categories. Each category has one Festival.
Each category has one or more curators (a user) and curators could have more than one category.
Submissions have one category and one festival (through it's category).
"current_user" is the user that is logged in
"current_festival" is the one festival that is currently taking new submissions
When a curator (a user) is logged in and they look at the index of submissions. They should only see submissions for which they are curator (through category). I'm stumped on how to generate the proper list of submissions. Here is what is in the controller now:
def index
#submissions = current_festival.submissions.all
end
This would return all the submissions for the current festival, not just from the categories that the current_user is the curator. What I want is something like this, but I don't know the proper syntax:
def index
#categories = current_user.categories.where(festival_id: current_festival.id)
#submissions = current_festival.submissions.where( category_id: "one of the #categories" )
end
Any ideas what the proper syntax would be?
This will give you all the submission that belongs to category which are created by current_user
def index
category_ids = current_user.categories.where(festival_id: current_festival.id).collect(&:id)
#submissions = current_festival.submissions.where(category_id: category_ids)
end

Adding a new record that has a foreign key relationship using new_foo_path(#bar)

I'm trying to add a new location to a restaurant using Ruby on Rails.
In the restaurants#show action I run:
<%= link_to 'Add Location', new_location_path(#restaurant) %>
And I get a URL: http://localhost:3000/locations/new.1, where 1 is the id of the restaurant. But the new location form doesn't appear.
What is the rails way to handle this simple case? Is using new_FOO_path even the right thing to be doing?
In this case, I shouldn't have a drop down to select the restaurant because I want the end user to only be able to add a location to their own restaurant. I would somehow need to have a hidden input with the restaurant ID in the add location form, and also validate the id on the backend.
I would create a nested resource in your routes.rb. Example:
resources :restaurants do
resources :locations
end
Then your link target would be new_restaurant_location_path(#restaurant). In your controller, you can find the restaurant via Restaurant.find(params[:restaurant_id]).
Alternatively, set the restaurant id as a GET parameter with new_location_path(:restaurant_id => #restaurant.id).

Assign user roles with CanCan?

Ive setup a application with two basic user roles.
A admin who can manage everything and a normal user and can create things (jobs & clients) but can not delete.
I'm a bit stumped though as to how can assign roles to the users. I assume it would be a case of adding a role column to my database? As user's are only created by the admin user. I need to add some sort of collection select to my form?
Can anyone point me in the right direction?
Edit: I tried the One role per user instructions as detailed on the cancan wiki here but i'm recieving the error uninitialized constant User::ROLES
Found an answer :)
I inserted this code..
ROLES = %w[admin user]
def role_symbols
[role.to_sym]
end
Into my User model and put <%= f.collection_select :role, User::ROLES, :to_s, :humanize %> into my form :)

Rails 3: validate that a record belongs to user

I have a HABTM relationship between Products and Categories. Those Categories belongs to a user.
At my product form, I only show checkboxes for the current user. But i want to validate this on model too, so users can't fake POST variables and assign it to invalid categories.
How can i do such validation?
Example: given a category_id 5, i have to check if this category belongs to current_user.id ( provided by devise ).
Thanks.
You can add attr_accessor: creator_id to your Post model. (creator_id is not in database )
And send current_user.id from form to Post's creator_id.
Then use model callbacks. For example after_validation:
after_validation do
if User.find(creator_id).categories.pluck(:id).include?(category_id)
true
else
errors.add :category, "is invalid for user"
end
end

Web app design questions - RoR 3

This is my first web app that i am developing and i have some design questions, i have a few book about RoR3 but i dont seem to find answers to my questions.
My application is based on Ruby on rails 3
I am not looking for detailed answers here, if you can just point me to a topic name that i could learn about that can answer my qustions, such as "names resources" , "hidden fields" .....
My questions:
1- How to send information between View A and controller B. Example, i am on the View for "Company" when i click create employee i am calling the "new view" for the employee so i am now on a different view, how can i pass to the new employee action the ID of the company? Since i am now on a different view ? i don’t want to use nested resources
What are the different ways to send information across different controllers/views
2- ruby URLs: i can view am item in my model via the URL: http://localhost:3000/Companies/1
I don’t want the url to contain the index of the item, each company has a name and i want to display this name in the url such as http://localhost:3000/Companies/myCompany
How can i change the url structure of rails?
For your first question, you can pass the parameters with the link (assuming you have employee and company variables accessible to your view):
Edit: this should work:
= link_to "create employee", :controller => "employees", :action => "new", :company_id => #company.id
And in the Employees controller:
def new
company_id = params[:company_id]
# check that company_id is not nil before doing stuff with it
end
I'm not sure why doing this ignores any extra parameters:
= link_to "create employee", new_employee_path, :company_id => #company.id
For your second question, this is what you're looking for.
Pass the company id as parameters at create employee link .
In the controller ,receive the params like
def new
company_id = params[:company_id]
....
end
For using some string instead of id , use gem 'friendly_id'
Make sure your reference string should be unique.