Reputation: 12189
I have got the following task to do:
There is 2 models: Order and User, and there is form for building a new order. This form must contains fields for building User association - name, phone. I have got no problems with it; I should just use accept_nested_attributes in Order model and build Order with nested User, it's ok. But if User with the same phone exists already I want just user_id for a new Order be installed as user_id of existed User without creating a new User. How can I do it better? I don't know how to build association using some condition. Thanks in advance.
Upvotes: 0
Views: 68
Reputation: 9173
Inside your create action of orders_controller.rb you could do something like this
def create
@user = User.find(params[:phone_number])
if @user
@order = @user.build_orders(order_params_without_user)
if @order.save
redirect_to your_path
else
render new
end
else
@order = Order.new(order_params_with_user)
if @order.save
redirect_to your_path
else
render new
end
end
end
private
def order_params_without_user
params.require(:order).permit(order attributes)
end
def order_params_with_user
params.require(:order).permit(order_attributes, user_attributes: [ user_attributes ])
end
You can simplify it even further by separating the @order.save if-else block in a method and then calling that method inside your create action like:
def create
@user = User.find(params[:phone_number])
if @user
@order = @user.build_orders(order_params_without_user)
order_save(@order)
else
@order = Order.new(order_params_with_user)
order_save(@order)
end
end
private
def order_params_without_user
params.require(:order).permit(order attributes)
end
def order_params_with_user
params.require(:order).permit(order_attributes, user_attributes: [ user_attributes ])
end
def order_save(order)
if order.save
redirect_to your_path
else
render new
end
end
If you are using rails 4 you can make two private methods order_params_with_user and order_params_without_user, with permitting user attributes in order_params_with_user and then simply pass them on the if-else blocks.
As you mentioned in your comment how can i use find_or_create
, if you are using rails 4 then you'll have to permit your attributes and you'll pass that to your find_or_create
method but since you want to permit different attributes in different conditions so it'll be better if you separate them out.
Upvotes: 0
Reputation: 1636
@user = User.find_or_create_by(phone_number: params[:phone_number])
This way, you only create the user record if it doesn't exist eliminating duplication.
Upvotes: 1