get user_id Devise in nested form rails 3.1 - ruby-on-rails

I'm follow this tutorial http://railscasts.com/episodes/196-nested-model-form-part-1 for nested form.
I have 3 model the first user.rb:
class User
has_many :boards, dependent: :destroy
has_many :posts, dependent: :destroy, :autosave => true
accepts_nested_attributes_for :boards
accepts_nested_attributes_for :posts
end
The second model its board.rb
class Board
has_many :posts, :dependent => :destroy , :autosave => true
accepts_nested_attributes_for :posts
belongs_to :user
end
The third model its post.rb
class Post
belongs_to :user
belongs_to :board
end
I want create a new post since a board form and I have in boards_controller.rb
def new
#board = Board.new
#board.posts.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #board }
end
end
def create
#board = current_user.boards.new(params[:board])
#board.user = current_user
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
With this 2 methods I get every attributes of posts in my views. in my console if I put after create a board Post.first I get:
1.9.2-p290 :007 > Post.first
=> #<Post _id: 4f0b0b211d41c80d08002afe, _type: nil, created_at: 2012-01-09 15:43:29 UTC, user_id: nil, board_id: BSON::ObjectId('4f0b0b1b1d41c80d08002afd'), content: "hello post 2">
But If you take a look I get user_id: nil.
In normal model I get user id for example in create action of controller I put #post.user = current_user.id or #post.user = current_user
How Can I get the user_id in nested model post through from nested forms?

def create
#board = current_user.boards.new(params[:board])
##board.user = current_user - you don't need this line, since you create new board record using current_user object
# assign current_user id to the each post.user_id
#board.posts.each {|post| post.user_id = current_user}
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end

You should be able to simply set the user_id property.
In your code you are assigning the current_user object to the association.
This should work:
def create
#board = current_user.boards.new(params[:board])
#board.user_id = current_user.id
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end

Related

Associate current_user by a controller in rails 4

I'm trying to associate a current_user.id to a #patient.medic_id via a controller.
I try this in my controller:
def create
# #patient = Patient.new(patient_params)
#patient = current_user.patients.build(patient_params[:medic_id => current_user.id])
respond_to do |format|
if #patient.save
format.html { redirect_to #patient, notice: 'Patient was successfully created.' }
format.json { render :show, status: :created, location: #patient }
else
format.html { render :new }
format.json { render json: #patient.errors, status: :unprocessable_entity }
end
end
end
This will automatically fill medic_id in the view with the current_user.id, but when I submit the form active record doesn't save the others parameters for patient like name, last_name, age, blood_type, etc.
This is my model /medic.rb (devise - user)
class Medic < ActiveRecord::Base
has_many :patients
end
This is my model /patient.rb
class Patient < ActiveRecord::Base
belongs_to :medic
end
And I need a way to call all registers (patients) from a medic-user, to a show view; what it is the best way to do this?
Thanks for the help.
To solve the problem when you create a patient:
medic_id = {medic_id: current_user.id}
current_user.patients.build(patient_params.merge(medic_id))
Assuming you have #medic in your show action, to get all patients of a medic-user:
#patients = #medic.patients
And in your show view, you can access #patients as an array.

Validating by user_id in Rails

I have this code that validates by user_id. If the category_name exists, this prevents the creation of a new Object. The code works but I don't believe this is best practice.
def create
#item_category = ItemCategory.new(item_category_params)
#item_category.user_id = current_user.id
search = ItemCategory.where(:name => #item_category.name,:user_id => current_user.user_id)
if search.blank?
respond_to do |format|
if #item_category.save
format.html { redirect_to :back, notice: 'Se ha creado la categoria' }
format.json { render action: 'show', status: :created, location: #item_category }
else
format.html { render action: 'new' }
format.json { render json: #item_category.errors, status: :unprocessable_entity }
end
end
else
respond_to do |duplicate|
duplicate.html { redirect_to #item_category, alert: 'Categoria Repetida' }
duplicate.json { render json: #item_category.errors, status: :unprocessable_entity}
end
end
end
Thanks.
It would be better to put the validation in your ItemCategory model...
class ItemCategory < ActiveRecord::Base
validates_uniqueness_of :name, :scope => :user_id
...
end

belongs_to association not populating user_id

I had two models and wanted to add a belongs_to association. A user has_many Places. To do this I did the following:
1) Created a migration using rails g migration AddUserToPlace user:references
This created a user_id column in my places table with the following migration:
add_reference :places, :user, index: true
However when I create new places the user_id column remains blank.
What am I missing?
EDIT:
create action
def create
#place = Place.new(place_params)
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render action: 'show', status: :created, location: #place }
else
format.html { render action: 'new' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
The user_id is not filled by default. When create new Places make sure to include the user_id in the parameters for example;
#place = Place.new();
#place.create(name: "jahn", user_id: #current_user.id)
Also try to enforce the presence of user_id in the PlaceModel
validates :user_id, presence: true
you should have something like this;
def person_params
params.require(:place).permit(:user_id, :..., :....)
end
`User_id` should be passed from the form. Otherwise for example you could do this;
def create
#place = Place.new(place_params)
#place.user_id = current_user.id
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render action: 'show', status: :created, location: #place }
else
format.html { render action: 'new' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end

undefined method `destroy' on Public Activity

User's can comment on a Screen and it's tracked by PublicActivity :
#comment.create_activity :create, owner: current_user, recipient: #comment.screen.user
and the comments are dependent: :destroy on the screen model.
But when i delete a screen, while the comments are deleted, the Record from PublicActivity for that comment still exists.
here's my Screens Controller:
def destroy
#activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
#activity.destroy #<-- Heres the Problem
#screen.destroy
respond_to do |format|
format.html { redirect_to root_path }
format.json { head :no_content }
end
end
But upon deleting a Screen, i'm getting undefined methoddestroy' for nil:NilClass`.
I read on Railscast:
it was due to calling the create_activity method after the object had
been destroyed.
According to the gem maintainers, you simply have to assume the record
will be destroyed, and call create_activity before the destroy
What am i missing?
Informations below
screen.rb
belongs_to :user
has_many :comments, :dependent => :destroy
comment.rb
belongs_to :user
belongs_to :screen
screens_contoller.rb
def create
#screen = current_user.screens.build(screen_params)
respond_to do |format|
if #screen.save
format.html { redirect_to #screen, notice: 'You successfully uploaded your Screenshot.' }
format.json { render action: 'show', status: :created, location: #screen }
current_user.add_points(2, 'Points for Uploading a Screenshot')
else
format.html { render action: 'new' }
format.json { render json: #screen.errors, status: :unprocessable_entity }
end
end
end
def destroy
#activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
#activity.destroy
#screen.destroy
respond_to do |format|
format.html { redirect_to root_path }
format.json { head :no_content }
current_user.substract_points(1, "Substraction for Deleting a Screenshot")
end
end
comments_controller.rb
def create
#screen = Screen.find(params[:screen_id])
#comment = current_user.comments.build(comment_params)
#comment.screen_id = #screen.id
respond_to do |format|
if #comment.save
# Create Record for Public Activity
#comment.create_activity :create, owner: current_user, recipient: #comment.screen.user
format.html { redirect_to #screen, notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: #comment }
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
#comment.destroy
respond_to do |format|
#activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
#activity.destroy
format.html { redirect_to :back }
format.json { head :no_content }
end
end
That's how my Screen Controller Destroy Action looks like right now:
def destroy
#screen = current_user.screens.find(params[:id])
#activity = PublicActivity::Activity.find_by_trackable_id(params[:id])
#activity.destroy
#screen.destroy
current_user.substract_points(1, "Substraction for Deleting a Screenshot")
respond_to do |format|
format.html { redirect_to root_path }
end
end
Again the same error:
This isn't tested, but this is what I think you should do.
First you can remove the references to activities in your screens_controller#destroy
Then in your comments_controller#destroy
#comment = current_user.comments.find(params[:id])
#activity = PublicActivity::Activity.find_by(trackable_id: (params[:id]), trackable_type: controller_path.classify)
#activity.destroy
#comment.destroy
Should be outside of your respond to block
Next in your comments model you should do something like this:
#comment.rb
private
before_destroy :find_and_destroy_comments
def find_and_destroy_comments
activity = PublicActivity::Activity.find_by(trackable_id: self.id, trackable_type: self.class.name)
if activity.present?
activity.destroy
end
end
calling the before_destroy method overrides the default ruby destroy method that is called during dependent: :destroy
Let me know if this works, but It should.

rails: creating models

Hi I have a model that looks like this:
The id of class and teacher is 1 to 1.
Class has_many grades
Grade belongs_to class
This is my home page controller:
#grade = Grade.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #grade }
end
This is my grade controller:
def create
class = Class.find(current_teacher.id)
****#grade = class.grades.build(params[:grade])
respond_to do |format|
if #grade.save
format.html { redirect_to #grade, notice: 'Grade was successfully created.' }
format.json { render json: #grade, status: :created, location: #grade }
else
format.html { render action: "new" }
format.json { render json: #grade.errors, status: :unprocessable_entity }
end
end
end
Currently I am getting this error on the line that has **
unknown attribute: class_id
How to fix it?
Another question is I also have
grade belongs_to student
student belongs_to grade
How do I add this to the create/new method as well?

Resources