VPNTIME
VPNTIME

Reputation: 761

Rails Mass Assignment--how to go about this

I have a receiver_id and sender_id that I am getting through hidden form fields. These attributes are attr_accessible, so they are mass assignable. However, I don't want it to be subject to mass assignment. How would I go about this without having to resort to hidden form fields and making the receiver and sender id attr_accessible?

controller

Class UsersController < ApplicationController
def show
    @user = User.find(params[:id])
    @first_name = @user.first_name
    @last_name = @user.last_name
    @wallpost = WallPost.new(params[:wall_post])
    @showwallposts = @user.received_wallposts
end

def create
    @wallpost = WallPost.create(params[:wall_post])
end

models

class WallPost < ActiveRecord::Base
  attr_accessible :content, :receiver_id, :sender_id
  belongs_to :receiver, :class_name => "User", :foreign_key => "receiver_id"
  belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
end


class User < ActiveRecord::Base
has_many :sent_wallposts, :class_name => 'WallPost', :foreign_key => 'sender_id'  
has_many :received_wallposts, :class_name =>'WallPost', :foreign_key => 'receiver_id'

in the view

    <%= form_for(@wallpost, :url => {:action => 'create'}) do |f| %>
      <%= f.hidden_field :receiver_id, :value => @user.id %>
      <%= f.hidden_field :sender_id, :value => current_user.id %>    
      <%= f.text_area :content, :class => 'inputbox' %>
      <%= f.submit 'Post', class: 'right btn' %>    
    <% end %>

Upvotes: 0

Views: 68

Answers (1)

Alex Peachey
Alex Peachey

Reputation: 4686

Yes, this is similar to what I imagined your set up might be.

So you want sender_id to be the the id of the current user.

So you should have:

def create
  @wallpost = current_user.sent_wallposts.create(params[:wall_post])
end

It doesn't matter then that receiver_id is mass_assigned as there is no problem assigning the receiver.

It seems you are also interested in restricting the receiver_id. You can do that as well:

def create
  receiver_id = params[:wall_post].delete(:receiver_id)
  @wallpost = current_user.sent_wallposts.build(params[:wall_post])
  @wallpost.receiver_id = receiver_id
  @wallpost.save
end

However, that doesn't really change the situation at all since there is no different between that and mass assigning the value. The only reason you would want to avoid mass assignment of that value is if there is some additional logic that you want to put in place around whether a user can send to another user. In which case it would be something like this:

def create
  receiver_id = params[:wall_post].delete(:receiver_id)
  if current_user.can_send_to(receiver_id)
    @wallpost = current_user.sent_wallposts.build(params[:wall_post])
    @wallpost.receiver_id = receiver_id
    @wallpost.save
  end
end

You of course would need to create some method that can determine if the user can send to that receiver. And at this point your action is getting very complex and I would refactor this whole thing to take this out of your controller action.

Upvotes: 1

Related Questions