문제

I have an app with the following relationships between models:

class ContentPartner < User

  has_many :events, dependent: :destroy
  has_many :videos, through: :events, dependent: :destroy

class Video

  belongs_to :event

class Event

  has_many :videos, dependent: :destroy

How can I create a new video so that it has the correct :event_id and :content_partner_id passed to it, without using nested resources (which I don't want) or creating a mass-assignement security issue by adding :event_id and :content_partner_id to the Video attr_accessible whitelist?

With my controller like this:

  def create
    @event = Event.find(params[:video][:event_id])   
    @video = @event.videos.create(params[:video])
    if @video.save
      flash[:success] = "Video uploaded!"
      redirect_to session[:return_to]
    else
      flash[:error] = "#{@video.errors.messages}"
      render new_video_path
    end  
  end

and no hidden_field in my @videos form, I end up with the error "Couldn't find Event without an ID"

but with:

    <%= f.hidden_field :event_id, value: @event.id %>

in my form, I get the error "Can't mass-assign protected attributes: event_id"

Is there a 3rd way to create a new video that belongs_to an event without using nested resources or compromising on mass assignments risks?

도움이 되었습니까?

해결책

Well, you can change your hidden_field to:

<%= hidden_field_tag :event_id, @event.id %>

And now in your controller, you can access that variable with:

Event.find(params[:event_id])

This should circumvent the mass-assign error. However, now any malicious user can edit that hidden field and add a video to any event he wishes. To fix this, you should find the event through an association. So if you have a current_user or current_content_partner, you should find the event like this:

current_content_partner.events.find(params[:event_id])

Now, a user is only able to access events he owns.

다른 팁

You are getting the error

1) "Couldn't find Event without an ID" : might be because params[:video][:event_id] is nil

2) "Can't mass-assign protected attributes: event_id" : because you are doing

@video = @event.videos.create(params[:video]) and params[:video] contains event_id as params[:video][:event_id] where event_id is a protected attribute

Setting a protected attribute (here event_id) through hidden_field is definitely not recommended, since any user can edit the value for that hidden field from the UI using any developer tool as said by @Ashitaka

You should use nested resources to get event_id directly from the URL.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top