Reputation: 434
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
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
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