redirecting with wrong parameter - ruby-on-rails

I have an app that allows users to follow/unfollow other users. This relationship is stored in the relationships table, which has the fields id, follower_id, and followed_id. When I call the destroy method to unfollow a user, it destroys the relationship, but then tries to redirect back to the followed user by using the destroyed relationships id and not the users id. This id is/was stored in the followed_id field of the relationships table. I don't know how to trouble shoot this in rails.
Here is the relationship controller
class RelationshipsController < ApplicationController
def create
#relationship = Relationship.new
#relationship.followed_id = params[:followed_id]
#relationship.follower_id = current_user.id
if #relationship.save
redirect_to User.find params[:followed_id]
else
flash[:error] = "Couldn't Follow"
redirect_to root_url
end
end
def destroy
#relationship = Relationship.find(params[:id])
#relationship.destroy
redirect_to user_path params[:id]
end
end

replace:
redirect_to user_path params[:id]
with:
redirect_to user_path(#relationship.followed_id)
#relationship is removed from db but you still have the object in memory.

def destroy
#relationship = Relationship.find(params[:id])
#followed_user_id = #relationship.followed_id
#relationship.destroy
redirect_to user_path #followed_user_id
end
Hope this may help :)

Related

How do I update attributes of a nested model?

I have a company model, that accepts_nested_attributes_for :users and my controller looks like this:
def create
#company = Company.new(company_params)
if #company.save
redirect_to root_url
else
render 'new'
end
end
private
def company_params
params.require(:company).permit(:name, :company_size , users_attributes: [:id, :name])
end
what I'd like to do is set the admin boolean I have in user to true.
Essentially what I'm doing is making a user sign up by creating a company, and also registering their user, and thus making the person registering the company an admin.
You can simply alter the User object before it is saved.
def create
#company = Company.new(company_params)
#company.user.admin = true
if #company.save
redirect_to root_url
else
render 'new'
end
end
You could also do this as a a model callback. However your implementation might be a little to naive. What happens if a user belongs to several companies?

converting the methods for a has_many association to a has_one association

I have 2 models, users, and common_apps.
users has_one :common_app.
Before this, I wrote the code as the users has_many common_apps, however I'm not sure how to rewrite that for a has_one association. The main confusion is how to structure 'new' in common_app controller.
When I try, I get an undefined method error.
undefined method `new' for #<CommonApp:>
This is my code -->
def new
if current_user.common_app.any?
redirect_to current_user
else
#common_app = current_user.common_app.new
end
end
def create
#common_app = current_user.common_app.build(common_app_params)
if #common_app.save
flash[:success] = "Common App Created!"
redirect_to root_url
else
redirect_to 'common_apps/new'
end
end
def show
#common_apps = current_user.common_app
end
how would you restructure this, if this were to be a has_one association?
I think I know how the 'create' one should be -->
def create
#common_app = current_user.build_common_app(common_app_params)
if #common_app.save
flash[:success] = "Common App Created!"
redirect_to root_url
else
redirect_to 'common_apps/new'
end
end
Your new action should look like this:
def new
if current_user.common_app.present?
redirect_to current_user
else
#common_app = current_user.build_common_app
end
end
You can also call build_common_app without any parameters passed to it, which will initialize an empty CommonApp for current_user.

Wants to create a new instance of books instead of update

What I want is to create a profile pages, where i can view the previous book field and if the customer change the text then it would create a new books.
I have the following models with has_many relationship
Customer -- ID, First, Last, Email
Book -- ID, Description
Book_Managers -- ID, Customer_id, Book_id, Visible
Right now what i have is a customer edit which allow me to see multiple form by rendering from many more models like books, phones, etc...
Here my customer Controller
def edit
#customer = Customer.find(params[:id])
if #customer.books.any?
#book = #customer.books.order("created_at DESC").first
else
#book = #customer.books.build
end
end
What i would like to see is if i created a new instance when going to book form i should see the last and able to modify "The JavaScript Bible" to something "The Java Bible" and it would not update it but just create a new version. Right now when going to the form book i see nothing. And if i do for some odd reason it was only allowing me to update.
class BooksController < ApplicationController
def create
#book = current_customer.books.build(params[:book])
if #book.save
flash[:success] = "Book Created"
redirect_to root_url
else
render 'customer/edit'
end
end
def index
#books = Book.all
end
def destroy
#book.destroy
redirect_to root_url
end
end
ADDED THIS
def update
#book = current_customer.books.build(params[:book])
if #book.save
flash[:success] = "Book Updated"
redirect_to root_url
else
render 'customer/edit'
end
end
To my book controller, the only problem right now is my association, i can't seem to find any book with the current customer. is there somethign wrong with my query?
There is some gems for versioning. This that : https://www.ruby-toolbox.com/categories/Active_Record_Versioning
You can do something like this :
def update
params = params[:book].merge(:previous_version => params[:id])
#book = current_customer.books.create(params[:book])
end
It will create a new book on each update. The last version will be the book without "previous_version".

How to permit creator to destroy his own record with Devise on Rails3

When the user is logged in, only the user who create the record can destroy his own record.
What should I add to the code below??
def destroy
#topic = Topic.find(params[:id])
#topic.destroy
flash[:notice] = "topic deleted!"
end
What you are looking for is not really devise but a authorization solution like CanCan.
Devise can only authenticate users and verify that they are logged in and active. What you need is a way to determine if the user has the right to delete this topic or not.
You can of course roll your own like this:
def destroy
#topic = Topic.find(params[:id])
if #topic.user_id == current_user.id
#topic.destroy
flash[:notice] = "topic deleted!"
else
flash[:error] = "not allowed"
end
end
(The code assumes you have a belongs_to :creator, :class_name => :user association set up in your Topic.. But you get the idea).
But using something like CanCan will make your life a whole lot easier and would reduce the code to something like this:
def destroy
#topic = Topic.find(params[:id])
authorize! :destroy, #topic
#topic.destroy
flash[:notice] = "topic deleted!"
end
With your ability file (See defining abilities) set up like this:
can :manage, Topic, :owner_id => user.id

ROR: Updating two models from one form

I have two models profiles and users on my form. After a user is created he can then move to editing his profile. The views work well. But when I click Save to update the editted profile. It doesn't update, but the flash notice displays that profile has been updated. What might be wrong? I'm not sure what went wrong. Below is the code.
class ProfilesController < ApplicationController
def new
##user.profile = Profile.new
#user = User.find(current_user.id)
#identity = #user.profile || #user.build_profile()
#identity.save
end
def update
#user = current_user
#identity = #user.profile
if #identity.update_attributes(params[:identity])
flash[:notice] = 'Profile was successfully updated.'
redirect_to(new_profile_path())
else
render :action => "new"
end
end
end
class UsersController < ApplicationController
def show
#user = current_user
#user = User.find(params[:id])
#identity = #user.profile || #user.build_profile()
#identity.save
end
......
end
Thanks for your assistance.
There are potentially a few things wrong here. But the best solution to this problem would be to simplify and use the built in rails features for editing associations.
What I suggest doing is using nested attributes, Ryan Daigle has a great article on them.
I'm not sure why you're calling save in a new action and not in a create, that doesn't feel right. Also check that the name of the model in the form you're submitting is identity and not user or profile.
Can a user exist without a profile?

Resources