Reputation: 3
I have two models: User
and Dream
. User
has_many :dreams
and Dream
belongs_to :user
. I have two controllers for users and dreams as well. I want to create new Dream
with form_for
with a reference to a particular User
. But it shouldn't be specified by me, it should somehow (and this is where I'm stuck) track on which User
's page I pressed "Create new dream"
, and create it for this User
.
I managed to do this with using only Users Controller (for managing Dreams as well), with passing user_id
parameter in URL, and with hidden field. But I realize this is not a great way to do it, because anybody can edit URL or hidden field's value and create new Dream
for any User
.
I'm looking for a way to make two controllers communicate with each other under the hood. Or maybe this is not what I need and I miss some conceptual nuance of MVC or whatever. I need someone to push me in the right direction.
Upvotes: 0
Views: 70
Reputation: 12514
I think that is the way things are done of such kind.
For:
anybody can edit URL or hidden field's value and create new Dream for any User
moderator
, superadmin
, admin
authentication
alone cannot do all the things you have to use some method of authorization
mechanism like cancan
, cancancan
, pundit
,etc.If any user modifies the hidden field value, you have to check if he is authorized to do so or not.
Upvotes: 0
Reputation: 26061
You can add an optional user_id param to the new action in the DreamsController. It that param build the new dream on that User.
def new
user_id = params[:user_id]
@dream = if params[:id].present?
User.find(params[:id]).dreams.build
else
Dream.new
end
end
Then your link will be something like
<%= link_to "Create New Dream", {:controller => "dream", :action => "new", user_id: user[:id]}%>
Upvotes: 1
Reputation: 392
If you have login functionality, then you can define a method in ApplicationController
that returns the user that matches the session token provided by the request, and then do current_user.dreams.create(params)
which will create the dream with reference to whichever user is returned by current_user
and never put any information about the user into the client's view.
If you don't have login functionality, then I wouldn't worry about the fact that it can be edited, since at that point anyone would be able to create a dream for any other user anyway just by visiting that page.
edit: e.g. I've often used something like this:
def current_user
@current_user ||= User.find_by(session_token: session[:session_token])
end
Upvotes: 1