Username in Profile for Rails - ruby-on-rails

Using RoR 2.3.8. I have the following codes:
user.rb
def to_param
"#{login.downcase.gsub(/[^[:alnum:]]/,'-')}".gsub(/-{2,}/,'-')
end
people_controller.rb
def show
#person = User.find(params[:id])
if current_user == #person
#posts = #person.posts.paginate(:page => params[:page], :order => order)
else
#posts = #person.posts.by_status('published').paginate(:page => params[:page], :order => order)
end
end
I have a column login in Users database where unique username is. People is just a controller to show some posts created by the user.
I will usually link to the index.html.erb under my people controller with the url http://localhost:3000/people/2 with the following code example in User's posts:
<%=h #post.user_name %>
I want the URL to be http://localhost:3000/people/victor where victor is the login for a user. This url should also actually show the profile show.html.erb in people controller.
What else do I need to do? Thanks!

I use the friendly_ID gem for this sort of thing - it's very straightforward - good luck

I would modify routes.rb, something like this:
match 'people/:login' => 'people#show', :as => 'login'
And then modify a people_controller.rb:
def show
#person = User.where(:login => params[:login]).first
end
edited after additional information
corrected error

Related

Rails 4 - Devise - admin approval of new users

I'm trying to figure out how to follow this devise tutorial to add 'approved' to the user model.
https://github.com/plataformatec/devise/wiki/How-To:-Require-admin-to-activate-account-before-sign_in
I have everything set up as shown in the tutorial, except when I save it all and try to click on the link called:
<%= link_to "Users awaiting approval", :action => "index", :approved => "false" %>
I get an error called:
undefined method `find_all_by_approved' for #<Class:0x007fbc5cf34dd0>
It highlights the second line of this users/index action:
def index
if params[:approved] == "false"
#users = User.find_all_by_approved(false)
else
#users = User.all
authorize #users
end
end
Does anyone know what else needs to be done (besides whats shown in the tutorial) to get this functionality to work?
Probably, you had typo issue. Below one should give you same results.
#users = User.where(approved: false)

Customizing Friendly_id URL

First I am sorry for my English
I am using Friendly_id gem to create Clean URL and it work just fine but instead of having a URL like this http://localhost:3000/profile/jack-sparo I want a URL like this http://localhost:3000/profile/1/jack-sparowhere 1 is the user_id, so how can I do it?
this is my config/routes
get "profiles/show"
get '/profile/:id' => 'profiles#show', :as => :profile
get 'profiles' => 'profiles#index'
and this is my Profile controller
def show
#user= User.find_by_slug(params[:id])
if #user
#posts= Post.all
render action: :show
else
render file: 'public/404', status: 404, formats: [:html]
end
end
If you have an id of the record in URL anyway, you don't need
Friendly_id gem. You need to tune routes.
But maybe you would be happy with something like this instead?
http://localhost:3000/profiles/1-john-smith
If so, you need to override to_param method in User model like
this:
class User < ActiveRecord::Base
def to_param
"#{id}-#{name}".parameterize
end
end
Now the profile_path(profile) helper will generate URL like
http://localhost:3000/profiles/1-john-smith
And, with this request, the User.find(params[:id]) in controller
will find profile with id 1 and cut all other stuff which was in URL.
So
http://localhost:3000/profiles/1-mojombo-smith
will link to the same profile as
http://localhost:3000/profiles/1-john-smith

Rails 4 - Nested Resources

User has_many Tickets.
Ticket belongs_to User (ticket.user_id)
routes.rb
resources :users do
resources :tickets
end
rake routes
user_tickets GET /users/:user_id/tickets(.:format) tickets#index
users/index.html.erb
<%= link_to("View User's Tickets", user_tickets_path(user)) %>
users_controller.rb
private
def set_user
#user = User.find(params[:id])
#tickets = #user.tickets
end
tickets_controller.rb
def index
#search = Ticket.search(params[:q])
#tickets = #search.result.paginate(:page => params[:page], :per_page => 25)
render 'shared/tickets.html.erb'
end
When I hover over link, it shows .../users/[the selected user's id]/tickets
When it goes to the ticket/index page, it shows ALL tickets, not just the tickets with the selected user's id.
I'm pretty sure my route is incorrect, or it may be something else entirely. Any help is appreciated.
EDIT
I think my problem is that I need to call #tickets in the tickets_controller/index method a variety of ways, because I want to use that view for #tickets.all, #user.tickets, #facility.tickets, etc (to keep it DRY).
The same index list of tickets needs to change, based on the link from whence it came (whether it comes from the user list, showing a list of all tickets by that user, or from the facility list, showing a list of all tickets by that facility). I'm just doing something horribly wrong somewhere.
Possible solution I will try:
Maybe I need to create custom routes, like get 'users_tickets' => "users#users_tickets", then put the #tickets conditions in that method and call the shared/tickets.html.erb that way.
Sounds like you need to step through the association. Did you use
tickets_controller.rb
def index
#user = User.find(params[:user_id])
#tickets = #user.tickets
end
in the controller? If this doesn't help, can you post the controller code?
Aren't you trying to whittle down #tickets rather than do another query?
Right now you're redefining #tickets when they hit the tickets index, and it doesn't care that you defined #tickets as just belonging to that user on the users_controller. It just ignores that because you're using direct assignment in your tickets_controller index action. You probably want something like:
tickets_controller.rb
def index
#search = Ticket.search(params[q])
#tickets = #search.result.where(user: #user)
#tickets = #tickets.paginate(:page => params[:page], :per_page => 25)
end
Not tested, but I think that's more what you're wanting.
Ok - I think I need to review nested resources again, because I thought they did what I wanted automatically...or maybe they do, and I just don't get it yet.
In any case, I ended up creating a custom route and custom method in users:
routes.rb
get 'user_tickets' => "users#user_tickets"
users_controller.rb
def user_tickets
#user = User.find(params[:id])
#search = Ticket.where(:user_id => #user.id).search(params[:q])
#tickets = #search.result.paginate(:page => params[:page], :per_page => 25)
render 'shared/tickets.html.erb'
end
then, called:
<%= link_to("View Tickets", user_tickets_path(:id => user.id)) %>
I will do the same for facilities, departments, etc. Not sure this is the best way, but it works.
Thanks everyone for stimulating my brain cells.

Redmine: Custom filter field for adding News

I'd like to add a custom filter field to "Add News" page in Redmine,
so that when I add a new news I could select group of users the email should be sent to.
The field itself is a list of Redmine User groups and every user is assigned to at least 1 of them.
Has anybody done this? Any suggestions would be appreciated
I've located the 3 files related to the issue:
/app/controller/news_controller.rb
/app/models/news.rb
/app/views/news/_form.html.erb
Environment:
Redmine version 2.2.1.stable.11156
Ruby version 1.8.7 (x86_64-linux)
Rails version 3.2.11
Environment production
Database adapter MySQL
Redmine plugins:
no plugin installed
So far I've done only 1 modification in Redmine, which sends added news to all registered users.
File: /app/modelsmailer.rb
Overview:
EDIT: Following your advice I moved mailer function to the controller:
def create
#news = News.new(:project => #project, :author => User.current)
#news.safe_attributes = params[:news]
#news.save_attachments(params[:attachments])
if #news.save
#news_added(#news)
if params[:group]
mail :to => GroupsUser.find(params[:group][:ids]).joins(:users).select("users.mail").compact,
:subject => "[#{#news.project.name}] #{l(:label_news)}: #{#news.title}"
else
render :new
end
end
end
But I'm getting error: NameError (uninitialized constant NewsController::GroupsUser): pointing to line
mail :to => GroupsUser.find
news_controller.rb:
def new
#news = News.new
#groups = GroupsUser.all
end
news/_form.html.erb:
<%= label_tag :group_ids "Groups"
<%= collection_select :group, :ids, #groups, :id, :name, {}, multiple: true %>
Edit:
I'm going to have to take a few guesses on what your controllers look like, but I'll give you something close. Based on the mailer function you provided, I'm assuming that was called out of the create controller after the News was saved. I would call the mail function after that. Something like this:
def create
news = News.new(params[:news]
if news.save
news_added(news)
send_mail_to_groups(params[:group][:ids]) if params[:group]
redirect_to ...
else
render :new
end
end
The mailing part should be removed from news_added
def news_added(news)
redmine_headers 'Project' => news.project.identifier
#author = news.author
message_id news
#news = news
#news_url = url_for(:controller => 'news', :action => 'show', :id => news)
end
in favor of its own new routine:
send_mail_to_users_by_group_ids(group_ids)
# Woo: Sent to all users, despite their email settings
mail :to => GroupsUser.find(group_ids).joins(:users).select("users.mail").compact,
:subject => "[#{#news.project.name}] #{l(:label_news)}: #{#news.title}"
end
You might want to add a where clause to only include active users.
I think that's about right. I'm doing it off the top of my head so there's probably a typo or error or two in there. Hopefully it points you in the right direction though.

Question about URL friendly links

I am trying to get my urls to look like this:
example.com/posts/id_of_post/title_of_post
I have this in my controller:
match ':controller/:id/:link', :controller => 'posts', :action => 'show'
Say I have a list of posts.. how can I link to them?
<%= link_to 'Show', post %>
Just gives the usual /posts/id
On another note, at the minute I am making a url-friendly link when a post is created and storing it in the database. Would it be better to create on the fly? Is that possible/better?
I saw this in an answer to another question:
def to_param
normalized_name = title.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '')
"#{self.id}-#{normalized_name}"
end
That would work if I could change the - to a /. Possible?
I recommend just doing this instead of the gsub stuff:
def to_param
"#{self.id}-#{title.parameterize}"
end
Downside is that if the title changes, the URL changes. Which is a downer.
So a lot of implementations will do
before_create :permanize
def permanize
permalink = title.parameterize
end
def to_param
"#{self.id}-#{permalink}"
end
This is what I did:
I added this to my post#create:
#post.link = (#post.title.parameterize)
I will give the user the option to edit the title for up to 5 mins after posting.
My route:
match "/posts/:id/:link" => "posts#show", :as => "story"
and my index view for posts
<%= link_to 'Show', story_url(post, post.link) %>

Resources