How to make an "if statement" for Rails has_many Association? - ruby-on-rails

I have the following in my UsersController
def show
#user = User.find(params[:id])
if current_user.id != params[:id] #! need to fix this
#answer = Answer.new
else
#answer = Answer.find(params[:id])
end
where each user has_many answers through a quizzes model. How can I write the if statement so if the answers are blank for that particular user it'll jump to creating a new quiz? (and if they aren't, to display the information).

I am not clear what are you trying to achieve as your code is doing unwanted check.SO if you just want to check if any user(assuming signed_in users) want to go to show action conditionally,i think you may try this:-
##assuming user has_many answers
##answer belongs_to user
def show
##get the user
#user = User.find(params[:id])
##verify if answer is present
if #user.answers.present?
#answer = #user.answers
else
#answer = #user.answers.new
end
end
The above logic can be used to has many through associations as well,just need to change to through model
Hope it helps :)

Related

Rails overrides data from objects

when i'm trying to edit my Students and change the subjects the have, the last student i edited loses all his subjects... Can Somebody Help me? Example: Added Math to Josh. Added Math and History to Jenny. Josh's subjects are now empty.
#students_controller
def edit
#subjects = Subject.all
end
def update
#subjects = Subject.find(subjects_params)
#subjects.each do |subject|
#student.subjects << subject
#student.save
end
if #student.update(student_params)
flash[:success] = "Success"
redirect_to students_path
else
flash[:danger] = "Error"
render :new
end
end
Not clearly sure what logic must be implemented, but i think you need to add subjects_attributes to student_params method. And also add accept_nested_attributes_for :subjects in Student model
After it you can do something like this
def update
#student.update(student_params)
end
This will add needed subjects to selected student.
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html more info about nested attributes
Also you can see simple_nested_form gem which wraps all nested attributes.

Polymorphic model user association

Rails 3.2. I am using the following code to associate user_id to the record:
# review.rb
class Review < ActiveRecord::Base
belongs_to :reviewable, :polymorphic => true, :counter_cache => true
end
# reviews_controller.rb
def create
#review = #reviewable.reviews.new(params[:review])
#review.user_id = current_user.id
if #review.save
flash[:success] = 'Thanks for adding your review.'
redirect_to #reviewable
else
flash[:error] = 'Error adding review, please try again.'
redirect_to #reviewable
end
end
I want to find a way to use this, but it keeps saying that the current_user is not defined, but I could find the current_user object:
def create
#review = #reviewable.current_user.reviews.create(params[:review]
if #review.save
flash[:success] = 'Thanks for adding your review.'
redirect_to #reviewable
else
flash[:error] = 'Error adding review, please try again.'
redirect_to #reviewable
end
end
If you can post your code to what the #reviewable object is, it might help to give a more specific answer. But if you want a one liner, you can do something like this:
#review = #reviewable.reviews.build(params[:review].merge({:user_id => current_user.id})
But personally, i think your original looks better as it's easier to read.
As an additional note, your second example also calls create and save. You don't need to call both, as create saves the object when accepting a hash of parameters. Save is nice to use if you want to initialize an object, modify it in some way, then save it later.
I think that the reason this does not work is because current_user is a method that is not defined on a reviewable.
The reviewable may belong to a user, in which case #reviewable.user.reviews.create... may be valid.

Create Child only and select a Parent in nested form?

Instead of creating a new Parent and also creating the children. Is it possible to select from a list of Parents and then only create the children that are assigned to a current user and that specific Survey?
Lets use this example:
class Survey < ActiveRecord::Base
has_many :questions
accepts_nested_attributes_for :questions
end
class Question < ActiveRecord::Base
belongs_to :survey
belongs_to :user
end
And then in the controller:
def new
# #survey = select menu of all Surveys
3.times do
question = #survey.questions.build
end
end
def create
# Saves new questions with current user
if #survey.save
flash[:notice] = "Success"
redirect_to #survey
else
render :action => 'new'
end
end
I'm not sure what the create and new actions would turn into. Any idea?
You can call the edit action on a existing survey passing the selected survey to it:
edit_survey_path(#survey)
Then you can load the selected survey in that action:
def edit
#survey = Survey.find(params[:id])
end
In the edit view, use a nested form to add/delete questions, and then, in the update action, updating your surveys attributes will also add and delete the questions.
def update
#survey = Survey.find(params[:id])
#survey.update_attributes(params[:survey])
redirect_to ...
end
All of this will work assuming you've set accepts_nested_attributes_for :questions in the survey model.
My answer here is a summary of Ryan Bates' screencast on nested forms which I think you've already seen, based on the similarity of your example and his.
What I'd like to point out here is that you can achieve what you want using exactly the same code, however using the edit/update actions on your parent model instead of new/create on the child model.
Edit:
In order to assign the current user to a survey question, do the explicit assignment in the new and edit action:
def new
#survey = Survey.new
3.times do
question = #survey.questions.build(:user_id => current_user.id)
end
end
def edit
# find the preselected Survey...
#survey = Survey.find(params[:id])
# This adds a (one) new empty question, consider doing it via Javascript
# for adding multiple questions.
#survey.questions.build(:user_id => current_user.id)
end
In your form for questions, add:
<%= form_builder.hidden_field :user_id %>
Don't forget to replace form_builder with your actual form builder object.
Now all the new questions will be assigned to the current user because the current user was submitted by the form along with the other attributes for questions.

finding a User object in ruby on rails

Ruby on rails noob here.
User fields relevant to this question: id (prim. key). Post fields relevant to this question: id, user_id (fk). The foreign key is user_id of Posts which is connected to id of Users. Is the following the right syntax? I want to grab the User object who posted the current post:
(this is in controllers/posts_controller.rb)
#id = Post.find(params[:id]).user_id
#user = User.find(#id)
You can see the context of the code below:
def sendMessage
##user = current_user
#id = Post.find(params[:id]).user_id
#user = User.find(#id)
UserMailer.welcome_email(#user).deliver
respond_to do |format|
format.html { render :nothing => true, :status => :ok }
end
end
The reason I'm asking is because an email is not getting sent to the user who created the post. Now, I know that this isn't an email issue because, as a test, I tried commenting out the two lines in question and simply using:
#user = current_user
...and this sends an email to the user who's logged in (but this isn't what I want).
Thanks in advance,
Matt
You should have your models set up as follows:
class Post < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Then in your controller you can do:
#post = Post.find(params[:id])
#user = #post.user
You should set the proper relations in the model.
I guess 'has_many :posts' in User and 'belongs_to :user' in Post.
Then you'll be able to do:
#user = Post.find(params[:id]).user

ROR: Updating two models from one form

I have two models profiles and users on my form. After a user is created he can then move to editing his profile. The views work well. But when I click Save to update the editted profile. It doesn't update, but the flash notice displays that profile has been updated. What might be wrong? I'm not sure what went wrong. Below is the code.
class ProfilesController < ApplicationController
def new
##user.profile = Profile.new
#user = User.find(current_user.id)
#identity = #user.profile || #user.build_profile()
#identity.save
end
def update
#user = current_user
#identity = #user.profile
if #identity.update_attributes(params[:identity])
flash[:notice] = 'Profile was successfully updated.'
redirect_to(new_profile_path())
else
render :action => "new"
end
end
end
class UsersController < ApplicationController
def show
#user = current_user
#user = User.find(params[:id])
#identity = #user.profile || #user.build_profile()
#identity.save
end
......
end
Thanks for your assistance.
There are potentially a few things wrong here. But the best solution to this problem would be to simplify and use the built in rails features for editing associations.
What I suggest doing is using nested attributes, Ryan Daigle has a great article on them.
I'm not sure why you're calling save in a new action and not in a create, that doesn't feel right. Also check that the name of the model in the form you're submitting is identity and not user or profile.
Can a user exist without a profile?

Resources