3

Ok, I know this is for the Saas course and people have been asking questions related to that as well but i've spent a lot of time trying and reading and I'm stuck. First of all, When you have a model called Movie, is it better to use Ratings as a model and associate them or just keep Ratings in an array floating in space(!). Second, here's what I have now in my controller:

def index

@movies = Movie.where(params[:ratings].present? ? {:rating => (params[:ratings].keys)} :   {}).order(params[:sort])
@sort = params[:sort]
@ratings = Ratings.all

end

Now, I decided to create a Ratings model since I thought It would be better. Here's my view:

= form_tag movies_path, :method => :get do

Include:
- @ratings.each do |rating|
 = rating.rating
 = check_box_tag "ratings[#{rating.rating}]"
= submit_tag "Refresh"

I tried everything that is related to using a conditional ternary inside the checkbox tag ending with " .include?(rating) ? true : "" I tried everything that's supposed to work but it doesn't. I don't want the exact answer, I just need guidance.Thanks in advance!

Update (the controller's method):

Here is the index method within my controller that is reading this hash - for clarity. I apologize for the fuzziness before.

def index    
  @all_stores = Product.all_stores
  @selected_stores = params[:stores] || session[:stores] || {}

  if @selected_stores == {}
    @selected_stores = Hash[@all_stores.map {|store| [store, store]}]
  end
  if params[:stores] != session[:stores]
    # session[:stores] = @selected_stores
    session[:stores] = params[:stores]
    redirect_to :stores => @selected_stores and return
  end
  @products = Product.order("created_at desc").limit(150).find_all_by_store(@selected_stores.keys).group_by { |product| product.created_at.to_date}
. . . etc
Elias Dorneles
  • 22,556
  • 11
  • 85
  • 107
  • As I see it, the primary purpose of a database is to store data that is subject to change over relative short time periods. The set of ratings your movies can have is relatively static, so I would just store this as an array constant in your movie class, e.g `RATINGS = ['R', 'PG', etc.]` – cdesrosiers Jun 10 '12 at 21:04
  • a constant? that makes sense. I didn't think about that. At first I had an instance variable @ratings = ['R','PG',etc.],then I thought that maybe I had to use a model.Merci. –  Jun 10 '12 at 21:31
  • No prob, that should make it a lot easier – cdesrosiers Jun 10 '12 at 21:37
  • that's what I did, I just read that I should put the constant in my model. good. –  Jun 10 '12 at 21:42

1 Answers1

12

Couple of things

1) .order(params[:sort]) opens you up for sql injection attacks, someone could potentially delete all of your users by putting this in the query string

http://localhost:3000/movies?sort=email%3B+DELETE+from+users+--

see rails 3 activerecord order - what is the proper sql injection work around?, this problem does not exist with .where, rails will sanitize the input for where method

2) minor thing, AREL delays making the actual call to the db until you iterate on the collection, so you can 'build' up queries, this syntax might be easier to understand then using ternary operator?

@movies = Movie.order(xxxxxx)
@movies = @movies.where(:rating => params[:ratings].keys) if params[:ratings].present?

3) for your ratings, like cdesrosiers says constant is fine, then your view

Movie::RATINGS.each do |rating|
  check_box_tag "ratings[]", rating # <input type="checkbox" name="ratings[]" value="PG" />

EDIT: maintain selected values

# controller
@selected_ratings = (params[:ratings].present? ? params[:ratings] : [])

# view
Movie::RATINGS.each do |rating|
  check_box_tag "ratings[]", rating, @selected_ratings.include?(rating)
  # <input type="checkbox" name="ratings[]" value="PG" checked="checked" />

note the [] in the naming of the checkbox, this will give you params[:ratings] as an array in your controller action

@movies = @movies.where("rating IN (?)", params[:ratings]) if params[:ratings].present? and params[:ratings].any?

some links

Community
  • 1
  • 1
house9
  • 20,359
  • 8
  • 55
  • 61
  • thanks man! yeah, when I try to resolve a problem I always do my queries directly,it's a bad habit. One day I ll forget about changing it in a real context. –  Jun 10 '12 at 22:11
  • Actually I m not sure about your answer. I'm still stuck at the same place. I'm trying to keep the checkboxes checked! I know that I can get an array of the checked values. But I'm having a hard time querying the array. That's what I meant by ternary. Not the one in the controller. I meant that I did this in my view: @movie.ratings.include?(rating) ? true: "" . That doesnt work. How do I keep the checkboxes checked? –  Jun 10 '12 at 22:29
  • I also tried to do params[:ratings].include?(rating). Too much of a newbie it seems. I tried a lot of things. I always ask here after I spent 2 days trying things most of the time. I have a big ego. –  Jun 10 '12 at 22:33
  • updated answer - basically it is doing `params[:ratings].include?(rating)` just stored and initialized empty array in case it is not present – house9 Jun 10 '12 at 22:38
  • man, I don't know what happened but I just did: = check_box_tag "ratings[#{rating}]",rating,params[:ratings].include?(rating) in my view, that's it , just this.I tried this thing 15 times already and it works now!!. I don't understand at all. I don't. –  Jun 10 '12 at 22:50