What does first.user = current_user mean/do and why is it working?
To start, I have 3 Models:
Location has_many :products
User has_many :products
Products belongs_to :user, :location
Now i have a nested form:
<%= nested_form_for @location do |f| %>
<%= f.error_messages %>
.............
<% f.fields_for :products do |product| %>
I was trying to find the right way to get my current_user association to work and suddenly out of pure chance found the right answer in this question, Nil foreign key in a nested form.
I put this piece of simple code in my controller and it finally gave my products to the current user_id:
@location.products.first.user = current_user
full -
def create
@location = Location.new(params[:location])
@location.products.first.user = current_user
end
My end goal was accomplished. Users have their own products created 开发者_高级运维at the specific location. Only thing i don't understand is why first.user = current_user
works and something simple like location = @location.current_user.products.build
doesn't. Could someone give me a great explanation on whats going on here and what the former means? Is this OK to have or is their a safer/better way?
Thank you, i do appreciate it.
The simplest way to define current_user
is
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
so current_user
is defined inside ApplicationController
class
whenever you trying to do
@location = Location.new(params[:location])
@location.current_user
you're trying to call method defined in other class as a method of the Location
instance
During this statement
@location.products.first.user = current_user
Rails, by default, assigns the id of the current_user to the left hand side. It is made possible by the internal call to the to_param. You can even override that method to return something else, even random stuff, but it wont be helpful :)
regarding the @location.current_user.products.build
,
this will not work because location and user are not related, if you want to make this work, you can do it by building a product in the new method and passing the current user id as a parameter to the method.
def new
@location = Location.new
@location.products.build
respond_to do|format|
format.html
end
end
UPDATE: I accept tumtu's comment, it is not advisable to put the user id as a hidden element.
精彩评论