Member action for custom actions on one field - ruby-on-rails

I have a User table with common fields: name, age, gender etc... In my application, when a new user signs up I want to check (approve or reject) his bio and profile photo to validate his account. I'm using ActiveAdmin and I wanted to have something like a scope in my User index where I see the "unchecked" user (I have done that part) and an action link(next to View, Edit and Delete) to approve or reject the bio/photo.
My problem is with this action link, I don't know how to do it. I've seen member_actions for custom actions, but I don't understand how it works and if I can modify one field one my user. Some help would be welcome on this.

ActiveAdmin lets you specify a custom action like approve
ActiveAdmin.register User do
member_action :approve, method: :put do
resource.approve!
redirect_to resource_path, notice: "Approved!"
end
end
Create a method in your Model to do what's necessary to approve, for example if approved is a boolean in your table, then
class User < ActiveRecord::Base
def approve!
update(approved: true)
end
end

Related

how can I create a form for User model which can be updated after successfully logged into application

Requirement: I need to create an application where user can logged in and can change the background color of that page, can change the font of the page and it should persist with session. so I am trying to create form which accept those attributes from user and can save in database. I am using devise for authentication.
How can I create form for user who is successfully logged into application(authentication is done by devise gem, so user table is already existing) and upon submission of form those attributes should get updated in user table. Any suggestion will be appreciated.
Q1 .What should be the name of controller and view for this form ?
Q2. How the routes can be define.
Q3. Whether controller should have update action to update user table with the extra attributes present in the form.
Thanks. Please comment below if I missed some information needed to provide. You can suggest me if you think this can be achieve in easier way also.
Whatever you want. Sounds li?ke you are just updated user attributes, so i would just use the User#update action
resources :users, only: [:update, :edit] #and any other user routes
? see 1
Also you will want to make sure that people can only edit their own account. In a before action you will want to add.
redirect_to root_path unless current_user == user_you_are_editing
What I would do:
Create a Model called UserPreferences that belongs_to :user, give this Model the attributes 'background_color', etc...
Add statement to user has_one :user_preferences
Create a form for the prefs like any Rails Model, that can only be accessed by current_user.
Use current_user.user_preferences to refer to these values, you can enhance this by placing alias methods in User, for example:
class User < ActiveRecord::Base
def background_color
self.user_preferences.background_color
end
end

Attaching default params with a form

In order for a user to use my search form, they type a user's name, press submit, then rails brings up that user's homepage. I am still a beginner, and the "homepage" the user arrives is a response to the GET method pointed at the URL http://localhost:3000/center/show_user?utf8=%E2%9C%93&name=test&commit=Search when I type the user name "test" in the search box.
In the controller action center#show_user, I have set #user = User.find_by(name: params[:name])
and in the view, it displays well with <%= #user.name %>.
I would like to make a form on the center#show_user page for creating a new "item". An item is defined at belonging to the user in the scheme and a user is defined as owning many items (a user has an item_id column and an item has a user_id column).
When this form is submitted, how do I include with it the current user_id, inherited from the params in the url on the page hosting the form? For example, if I go to the page of the user named "sample_user", I want to be able to submit a "new item" form and have the user_id automatically included along with that form.
'Central' controller code for this page is
def show_user
#user = User.find_by(name: params[:name])
end
Just add
<%= hidden_field_tag "user_id", current_user.id %>
to form.
You should create the "item" through the relation with the user. That means:
Given this in your user model:
class User < ActiveRecord::Base
has_many :items
end
Do the following in the controller:
def create
#user = User.find_by(name: params[:name])
#user.items.create(params[:item])
# redirect_to or something different...
end
This will automatically build the relation for you (basically filling in the user_id field for you). The reason for doing it this way is that users can't mess with your form and fill in other user ids in the hidden field.

How to redirect from one action of controller A to an action of controller B and back in Rails?

I have two associated models, Employee and Company:
class Employee < ActiveRecord::Base
attr_accessible :name
belongs_to :company
attr_accessible :company_id
end
class Company < ActiveRecord::Base
attr_accessible :name, :industry, :owner
has_many :employees
end
What I want to implement is that when, in the new employee form, the user types a company name that doesn't exist he/she should be redirected to the new company form, with the name field already filled with the value of the previous form, fill it in for the company to be created and then get redirected to the "employee successfully created" page (but if and only if the company is created first).
I have managed to create a company at the same time the employee is created, with the below code:
def create
#employee = Employee.new(params[:employee])
#company = Customer.find_or_create_by_name(params[:company][:name])
#company.employees << #employee
#company.save
#employee.save
end
However, this doesn't give me the option to fill in the rest of the company information.
Experimenting with redirect_to, I have also managed to send the user to the edit company form.
# one way to tell if the company has all its attributes filled
if #company.industry.blank?
redirect_to edit_company_path(#company), notice: "Please edit the company details" and return
end
*the and return statement is necessary as otherwise I get a "The redirect_to was called multiple times" error*
However, this is not the desired behaviour - for two reasons:
The employee is created even when the company is not.
The user is not informed about the employee creation.
So, my thinking is that I am redirecting to the company controller and the create action the right way and that I should somehow redirect back to where I was (right before the #employee.save) in the employee controller. But how? Also, is that the best and "most-rails" way to do it?
One option I see is to save employee data in session (session[:temp_employee] = params[:employee]), then redirect to creating the company. In the company controller, after the company is saved you could check if employee is present in the session then redirect client back to create action of the employees controller.
This would additionally require you to:
Enable access to create action via path (like: get 'create', to: 'employees#create')
In the employees create action take for attributes from session variable if it is present, otherwise fallback to the params hash.

Hide user id in the url bar

In my rails application I currently have a load of users who each have a registered user id.
If I go in to my users index and click on a users show page I get the following example header.
localhost:3000/users/3
Now I don't like this as it easily allows people to skip through users in the header.
How would I go about doing the following so that it shows the user.username field instead e.g.
localhost:3000/users/adamwest
You can define a to_param method on the User model.
class User
...
def to_param
name
end
...
end
Then every generated URLs will have name instead of id as a user identifier.
sid = User.new :name => 'sid'
user_path(sid) #=> "/users/sid"
Of course, in the controller, you have to find user by name.
class UsersController
...
def show
#user = User.find_by_name(params[:id])
end
...
end
I also suggest you to take a look at friendly_id gem.
FriendlyId is the “Swiss Army bulldozer” of slugging and permalink
plugins for ActiveRecord. It allows you to create pretty URL’s and
work with human-friendly strings as if they were numeric ids for
ActiveRecord models.

anonymous and registered user implementation with acts_as_commentable?

I am using acts_as_commentable and am curious if anyone has any good ideas on how to allow for anonymous and registered users to post comments? Meaning, if a registered user is authenticated, I want the comment to be marked with their name, etc. But I also want an anonymous user to be able to comment and have a name and email address recorded. I am using Devise for authentication.
I have an idea on how to make this work but it feels a little hacky to me. Wondering if anyone has any thoughts.
I don't know your plugin, but if you use this one (https://github.com/jackdempsey/acts_as_commentable), it seems very basic...
The Comment model has a relation to a user which is not mandatory.
So in your new comment form, I would just add two text_field_tags if the user is not logged (text_field_tag :first_name, text_field_tag :last_name).
And I'd just write the create action for comments like this :
def create
#comment = Comment.new(:commentable => #your_object, :user => current_user, :first_name => params[:first_name], :last_name => params[:last_name])
...
end
if the user is not logged, current_user will be nil and that won't cause any problem.
You can write an helper method to display the name for a comment depending it has a user or not like this...
# Displays the user's login if any or else the first name and last name
def displayed_name(comment)
comment.user ? comment.user.login : "#{comment.first_name} #{comment.last_name}"
end

Resources