suely
suely

Reputation: 434

association in rails 3 associate surveys to an user

I' am working with rails 3.2.1, ruby 1..9.2, devise 1.5.3, my app is a survey builder...something like surveymonkey, I have some problems with the associations, because I used belongs_to and has_many im my models, I need that a survey belongs just to one user, but if I login as diferents users I can see all the surveys,my app don't associate a survey to a user...all the users can see all the surveys, can you help me with this issue?, thanks in advance, here is my code.

my controller:

class AsurveysController < ApplicationController
  # GET /asurveys
  # GET /asurveys.json
  def index
    @asurveys = Asurvey.all

      respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @asurveys }
    end
  end

  # GET /asurveys/1
  # GET /asurveys/1.json
  def show
    @asurvey = Asurvey.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @asurvey }
    end
  end

  # GET /asurveys/new
  # GET /asurveys/new.json
  #def new
    #@asurvey = Asurvey.new
    #3.times { @asurvey.questions.build }

    #respond_to do |format|
    #  format.html # new.html.erb
    #  format.json { render json: @asurvey }
    #end
 #end
  #ejemplo railscast para 3 preguntas y 4 respuestas
  def new  

  @asurvey = Asurvey.new  
  3.times do  
    question = @asurvey.questions.build  
    4.times { question.answers.build }  
  end  
end
  #

  # GET /asurveys/1/edit
  def edit
    @asurvey = Asurvey.find(params[:id])
  end

  # POST /asurveys
  # POST /asurveys.json
  def create
    @asurvey = Asurvey.new(params[:asurvey])

    respond_to do |format|
      if @asurvey.save
        format.html { redirect_to @asurvey, notice: 'Encuesta creada exitosamente.' }
        format.json { render json: @asurvey, status: :created, location: @asurvey }
      else
        format.html { render action: "nueva" }
        format.json { render json: @asurvey.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /asurveys/1
  # PUT /asurveys/1.json
  def update
    @asurvey = Asurvey.find(params[:id])

    respond_to do |format|
      if @asurvey.update_attributes(params[:asurvey])
        format.html { redirect_to @asurvey, notice: 'Encuesta actualizada exitosamente.' }
        format.json { head :ok }
      else
        format.html { render action: "editar" }
        format.json { render json: @asurvey.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /asurveys/1
  # DELETE /asurveys/1.json
  def destroy
    @asurvey = Asurvey.find(params[:id])
    @asurvey.destroy

    respond_to do |format|
      format.html { redirect_to asurveys_url }
      format.json { head :ok }
    end
  end
end

my models:

asurvey.rb

class Asurvey < ActiveRecord::Base
  belongs_to :user
  has_many :questions, :dependent => :destroy
  #:dependent => :destroy para que cuando eliminemos una encuesta se eliminen también todas sus preguntas.
  accepts_nested_attributes_for :questions, :reject_if => lambda { |a| a[:content].blank? } , :allow_destroy => true   
  #accepts_nested_attributes_for para poder gestionar las preguntas a través de Survey. Con esto podremos crear, actualizar y

destruir preguntas cuando actualicemos los atributos de una encuesta. #el nombre de atributo para la caja de selección: _destroy. Cuando tenga un valor true (cuando haya sido marcada), el registro será eliminado al enviar el formulario. end

question.rb

> class Question < ActiveRecord::Base   #survey_id para relacionarlo con
> la encuesta y un campo de contenido para albergar el texto de la
> pregunta.
>      has_many :answers, :dependent => :destroy     accepts_nested_attributes_for :answers, :reject_if => lambda { |a|
> a[:content].blank? }, :allow_destroy => true      end

answer.rb

class Answer < ActiveRecord::Base
  belongs_to :question 
end

user.rb

>     class User < ActiveRecord::Base
>       # Include default devise modules. Others available are:
>       # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
>       
>       has_many :asurveyse
>       
>       devise :database_authenticatable, :registerable,:confirmable,
>              :recoverable, :rememberable, :trackable, :validatable
>     
>       # Setup accessible (or protected) attributes for your model
>       attr_accessible :email, :password, :password_confirmation, :remember_me,
>                       :tipo_tarjeta, :numero_tarjeta, :fecha_vencimiento, :nombre_en_tarjeta,
>                       :cvv, :nombre, :apellidos, :mail_facturacion, :mail_facturacion_alternativo,
>                       :nombre_empresa, :pais, :direccion,:codigo_postal, :telefono, :numero_orden_compra 
>                       
>                       #validacion de presencia de campos, no pueden estar en blanco
>       #validacion de presencia de campos, no pueden estar en blanco
>       validates_presence_of :numero_tarjeta,
>       :message => ": ingrese numero de tarjeta (15 digitos)"
>       validates_presence_of  :nombre_en_tarjeta,
>       :message => ": ingrese el nombre que aparece en su tarjeta"
>       #validates_presence_of  :fecha_vencimiento,
>       #:message => ": ingrese fecha de vencimiento de su tarjeta"
>       validates_presence_of  :cvv,
>       :message => ": ingrese cvv "
>       #validacion de ingreso de campos "datos personales"
>       validates_presence_of :nombre, 
>       :message => ": ingrese su nombre"
>       validates_presence_of :apellidos,
>       :message => ": ingrese sus apellidos"
>       validates_presence_of :mail_facturacion,
>       :message => ": ingrese mail de facturacion"
>       validates_presence_of :mail_facturacion_alternativo,
>       :message => ": ingrese mail alternativo de facturacion"
>       validates_presence_of :nombre_empresa,
>       :message => ": ingrese nombre de su empresa"
>       validates_presence_of :direccion,
>       :message => ": ingrese direccion de su empresa"
>        validates_presence_of :codigo_postal,
>       :message => ": ingrese codigo postal"
>       validates_presence_of :telefono,
>       :message => ": ingrese telefono de su empresa"
>       validates_presence_of :numero_orden_compra,
>       :message => ": ingrese numero de orden de compra"
>       #largo de campos, formato mail
>       validates_length_of :numero_tarjeta, :minimum => 16, :allow_blank => true, :message => "El numero debe tener al menos 16
> digitos de longitud"  
>       validates_length_of :nombre_en_tarjeta, :minimum => 2, :allow_blank => true, :message => "minimo 2 caracteres"  
>       validates_length_of :cvv, :in => 3..4, :allow_blank => true, :message => "(en Mastercard y Visa son los 3 ultimos digitos impresos
> al dorso de la tarjeta, en American Express son los 4 numeros impresos
> en el frente de la tarjeta arriba de los ultimos digitos grabados en
> relieve)" 
>       validates_length_of :nombre, :minimum => 2, :allow_blank => true, :message => "minimo 2 caracteres" 
>       validates_length_of :apellidos, :minimum => 4, :allow_blank => true, :message => "minimo 4 caracteres" 
>       validates_format_of :mail_facturacion,
>       :with => /^[A-Z0-9._%-]+@([A-Z0-9]+\.)+[A-Z]{2,4}$/i, :message => "formato incorrecto"
>       validates_format_of :mail_facturacion_alternativo,
>       :with => /^[A-Z0-9._%-]+@([A-Z0-9]+\.)+[A-Z]{2,4}$/i, :message => "formato incorrecto en mail alternativo"
>       validates_length_of :nombre_empresa, :minimum => 4, :allow_blank => true, :message => "minimo 4 caracteres" 
>       validates_length_of :direccion, :minimum => 4, :allow_blank => true, :message => "minimo 4 caracteres"   
>       validates_length_of :codigo_postal, :minimum => 7, :allow_blank => true, :message => "minimo 7 caracteres" 
>       validates_length_of :telefono, :minimum => 7, :allow_blank => true, :message => "minimo 7 caracteres" 
>       validates_length_of :numero_orden_compra, :minimum => 2, :allow_blank => true, :message => "minimo 2 caracteres" 
>     
>       #validates_length_of :password, :minimum => 6, :allow_blank => false                     
>                       
>     end

Upvotes: 0

Views: 279

Answers (2)

thorsten m&#252;ller
thorsten m&#252;ller

Reputation: 5651

In your Asurveyscontroller replace

@asurveys = Asurvey.all

by something like:

@asurveys = current_user.asurveys

(that's assuming, that you can access the currently logged in user with current_user)

In the show action you can do:

@asurvey = current_user.asurveys.find(params[:id])

This will ensure, that even if another user maliciously posts an id that doesn't belong to his surveys, he won't get to see it.

The other actions would need similar changes.

A lot would depend on how you handle your user login. I don't se any before_filters in you controller. You would need to add some more details here.

It would be a bit difficult to fully explain how to handle logins here. To test the code you could add something like

current_user = User.find(1)

assuming there is a user with this id in your database. Just set to a valid user object and then see, if this works like you want it to.

Upvotes: 1

zsquare
zsquare

Reputation: 10146

You need to look into Rails nested resources. This rails cast deals with the topic. You could also refer to this section of the Rails routing documentation.

Upvotes: 0

Related Questions