In my app there's a user model with an admin role. I want admins to be able to create new admins, so on the users/edit page I'm hoping to create an admin-visible checkbox that, when checked turns the user into an admin. The code I'm using is here. Everything works other than the checkbox bit, which is why I'm asking. I'm new to Rails, and I just can't figure out how to scrape the admin checkbox info and use it to alter the admin attribute (which is attr_protected for security reasons).
My edit form
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<% if signed_in? %>
<% if current_user.admin? %>
<h3> Click to Switch On/Off Admin
<%= check_box_tag(:admin) %></h3>
<% end %>
<% end %>
<%= f.submit #string, class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
The relevant lines of my user.rb file
before_save :toggle_admin
private
def toggle_admin
if self.admin == true
self.toggle!(:admin)
end
end
What am I doing wrong? It doesn't toggle anything when I submit.
Thanks!
Sasha
Actually problem is because you had added :admin checkbox incorrectly. You have to do it like this:
<%= f.check_box :admin %>
It will produce input with correct name:
<input type="checkbox" id="user_admin" name="user[admin]" value="0" />
So then you will have correct params hash which is sent after form submission.
For additional details please check Rails documentation: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box
Update #1
If in your case you want to use toggle for security reasons, just change before_save to after_save, because toggle works like this:
User.last.toggle!(:admin)
SQL output:
1.9.3p194 :007 > User.last.toggle!(:admin)
User Load (0.6ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
SQL (83.8ms) UPDATE `users` SET `admin` = 1 WHERE `users`.`id` = 13
=> true
1.9.3p194 :008 > User.last.toggle!(:admin)
User Load (0.6ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
SQL (76.7ms) UPDATE `users` SET `admin` = 0 WHERE `users`.`id` = 13
Update #2
In principle, you can implement it using a virtual attribute for checkbox.
after_save :toggle_admin
attr_accessor :adminify
attr_accessible :adminify
private
def toggle_admin
if self.adminify == "1"
self.toggle!(:admin)
end
end
Check tutorial about virtual attributes in Rails: http://railscasts.com/episodes/167-more-on-virtual-attributes
Related
I am trying to make a contact me form in Rials 5 with the built in Mail features.
I put it together a lot like a regular controller and views with a Mailer as the model. But when I have it all written out I get the error:
undefined method `model_name' for #ContactMailer
Contact is the name of the Mailer.
The error comes up when I try to view the new.html.erb page with rails server running. It looks like this:
Screen Shot
Here is the code I am working with:
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = ContactMailer.new
end
def create
#contact = ContactMailer.new(params[:name, :email, :message])
if #contact.deliver
flash[:success] = "Your message has been sent."
else
flash[:error] = "There was a problem sending your message."
render 'new'
end
end
And
new.html.erb
<%= form_for #contact do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control', required: true %></div>
<div class="form-group">
<%= f.label :message %>
<%= f.text_area :message, class: 'form-control' %>
</div>
<%= f.submit "Send", class: 'btn btn-default' %>
<% end %>
There is also the generated Mailer and views, but I have not changed anything with those.
From what I have been able to research the error could be that I have not initialized the #contact variable, but I believe that I have. And now I am lost. Any help would be appreciated.
As additional information:
My plan is for this contact form to send an email using send grid on Heroku.
You are trying to build a mailer.Thats not how they are used. They are not models.
Instead you would do something like:
ContactMailer.some_method_you_added_to_your_mailer(params[:name, :email, :message]).deliver_now
You don't use new on them.
Suggest you read over http://guides.rubyonrails.org/action_mailer_basics.html .
I have a page in my rails application that shows a list of listings (paginated using will_paginate). I am trying to find a good gem to implement searching and sorting with the list on this page. The Ransack gem looked like what i needed but i'm running into an issue with it. This is what my code looks like right now with the Ransack gem.
My model (didn't include the whole model, didn't want the validations and extra code to get in the way):
UNRANSACKABLE_ATTRIBUTES = ["id", "state", "show_email", "email", "show_phones", "primary_phone", "secondary_phone", "updated_at", "user_id"]
def self.ransackable_attributes auth_object = nil
(column_names - UNRANSACKABLE_ATTRIBUTES) + _ransackers.keys
end
My controller action:
def index
#search = Listing.search(params[:q])
#listings = #search.result.paginate(page: params[:page], per_page: 20, joins: "LEFT OUTER JOIN attachments ON listings.id = attachments.attachable_id", select: "listings.*, COUNT(attachments.id) AS photos", group: "listings.id", order: "listings.created_at DESC, listings.title ASC, listings.id DESC")
#search.build_sort if #search.sorts.empty?
end
My search form on the page:
<div class="advanced-search">
<%= search_form_for #search do |f| %>
<div class="search-by">
<div class="search-field">
<%= f.label :title_cont, "Title Contains" %>
<%= f.text_field :title_cont %>
</div>
<div class="search-field">
<%= f.label :description_cont, "Description Contains" %>
<%= f.text_field :description_cont %>
</div>
<div class="search-field">
<%= f.label :price_gteq, "Price Between" %>
<%= f.text_field :price_gteq %>
<%= f.label :price_lteq, "and" %>
<%= f.text_field :price_lteq %>
</div>
</div>
<div class="sort-by">
<%= f.sort_fields do |s| %>
<%= s.sort_select %>
<% end %>
</div>
<div class="search-actions">
<%= f.submit "Search" %>
</div>
<% end %>
</div>
My route:
resources :listings do
collection do
match 'search' => 'listings#index', via: [:get], as: :search
end
end
With everything i have in place now i have been able to get the application to successfully search and sort the listings.
My question: The sort_select field is showing everything option that is "ransackable". Is there a way to make one attribute available for the searching, but not the sorting? For example i want the ability to search on the description attribute but it doesn't make any sense to include that attribute in the sorting. How can i use an attribute in one and not the other? Thanks for any help and let me know if my question is not clear enough.
Couldn't figure out how to get the values i wanted into the dropdown so i just used links instead. Here's what i ended up with for the sorting.
Sort by <%= sort_link #search, :title %> | <%= sort_link #search, :price %> | <%= sort_link #search, :created_at, "Date Listed" %>
Listing Model - belongs_to :area
Area Model - has_many :listings
I'm trying to implement a search using Ransack with check boxes; where user checks selected areas, search returns all the listings of the areas selected.
<%= search_form_for #search do |f| %>
<% areas = Area.all %>
<% areas.each do |area| %>
<%= check_box_tag('q[area_id_eq][]', area.id) %>
<%= area.location%>
<% end%>
<%= f.submit "SEARCH" %>
<% end %>
Console output:
Parameters: {"utf8"=>"✓", "q"=>{"area_id_eq"=>["1", "2"]}, "commit"=>"SEARCH"}
Completed 500 Internal Server Error in 4ms
NoMethodError - undefined method `to_i' for ["1", "2"]:Array:
Just not sure how to implement it to accept multiple check box values.
Instead of using "area_id_eq", use "area_id_any". You'll also want to check to make sure that your parameters are selected:
<%= search_form_for #search do |f| %>
<% areas = Area.all %>
<% areas.each do |area| %>
<%= check_box_tag('q[area_id_eq_any][]', area.id, (params[:q][area_id_eq_any].include? area.id.to_s) ? true : false ) %>
<%= area.location%>
<% end%>
<%= f.submit "SEARCH" %>
<% end %>
I am building an application in which when the user log in as an admin it will have the list of registered users and have four links show,edit destroy and settings.What i want is when the admin click on the settings link it will have the view of check boxes in which admin decides the permission of users to read,edit,create and destroy of the model available in an application.
Thanks in advance.
If I understand you correctly you are looking for a view that sets the settings for one user.
Since you didn't give any details on your model I'll assume the Model is called User and the permissions are just boolean fields on that model.
Similar to this:
User
- can_read
- can_create
- can_destroy
- can_edit
I would then implement the view like this:
<%= form_for #user do |f| %>
<%= flabel :can_read %>
<%= f.check_box :can_read %>
<%= flabel :can_create %>
<%= f.check_box :can_create %>
....
<%= f.submit %>
<% end %>
Or shorter:
<%= form_for #user do |f| %>
<% [:can_read, :can_create, :can_edit, :can_delete].each do |permission| %>
<%= flabel permission %>
<%= f.check_box permission %>
<% end %>
<%= f.submit %>
<% end %>
The controller code would obviously look like this:
def edit
#user = User.find(params[:id]
end
def update
#user = User.find(params[:id]
#user.update_attributes(params[:user])
end
userhome_controller:
def edit_reviewer_email
#user = User.find(params[:id])
end
edit_reviewer_email:
<div class="pagetop center">
<%= form_for #user, update_reviewer_email_userhome_path(#user) do |f| %>
<%= f.label :email %><br />
<%= f.text_field :email, :size => 1 %>
<%= f.submit %>
<% end %>
</div>
error:
undefined method `stringify_keys' for "/userhome/18/update_reviewer_email":String
Should i be using form_tag when the model is accessed via a different controller?
I am looking for a rails 3 tutorial that covers a variety of forms if you know of any.
Thanks!
Your controller needs to limit its request to a single record (you can just use find):
#user = User.find(params[:id])
Or if you want to stick with a where statement:
#user = User.where("id = ?", params[:id]).first