0

Im learning Rails and I'm just wondering if some code I wrote is correct and safe. I have two models, a user and post model. The posts belong to users, so I want to pass the user_id automatically to post when the object is created. I used an assign_attributes method in the post controller to set the user_id using the current_user helper provided by devise. Below is my relevant code. Again I want to know if this is correct or if there is better way of doing it.

def create
@post = Post.new(params[:post])
@post.assign_attributes({:user_id => current_user.id})

end

Post Model

class Post < ActiveRecord::Base

attr_accessible :content, :title, :user_id

validates :content, :title, :presence => true

belongs_to :user

end

User model

class User < ActiveRecord::Base

devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me


has_many :posts

end

3 Answers 3

2

You're pretty close. Since you've 1) been provided the current_user convenience helper by Devise, and 2) configured User and Post as a has_many/belongs_to relationship, it makes sense to create the new post, then append it to current_user. Then, in your Post model, you'll want to break up validations for individual attributes – the way you've listed :content, :title in sequence won't work.

# app/controllers/posts_controller.rb
def create
    post = Post.create(params[:post])
    current_user.posts << post
end

# app/models/post.rb
class Post < ActiveRecord::Base

    attr_accessible :content, :title, :user_id

    validates :content, :presence => true
    validates :title, :presence => true

    belongs_to :user
end
Sign up to request clarification or add additional context in comments.

5 Comments

"current_user.posts << @post' ... How does this work? Append the new object the array of user.posts? But how is the value for user_id passed?
Precisely – post is appended to current_user. user_id no longer needs to be passed explicitly because the foreign key association between a post and current_user is automatically made when appending the post to the current user. This sort of relational mapping is just one of the conveniences that ActiveRecord affords.
Also, note that I've removed the @ before post. Since the create method will (likely) not be rendering out a view, there's no need to assign an instance variable... a local variable will suffice and (very nominally) reduce memory allocation.
Did this answer help address your question? Bear in mind that there are any number of ways to create has_many relationships... the method I depicted just so happens to be a fairly simple and idiomatic way of accomplishing it.
Yeah zeantosi... Thanks a lot for the clarification.
0

I don't think that is necessary since you have already created the relationship between posts and users. If you nest the posts resources into the user, it will automatically create the relationship between the 2 models.

In routes.rb

resources :users do
  resources :posts
end

With that done, you will now reference posts as @user.post. I have already shown an example in this question.

1 Comment

I know that would work, but I dont want to nest these routes.
0

I would say something like this :

def create
    params[:post][:user_id] = current_user.id
    @post = Post.new(params[:post])
    @post.save
end

or

def create
  @post = Post.new(params[:post])
  @post.user = current_user
  if @post.save
  ...
  else
  ...
  end
end

or

def create
  @post = @post.new(params[:post])
  @post.user_id = current_user.id
  @post.save
end

You could put the user_id in the params but that would not be safe. user_id should not be in 'attr_accessable' so it will be protected for mass_assignment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.