Class.where(obj:"someone") with index.html.erb - ruby-on-rails-4

I've got some problem with method in tittle.
I have got:
model group title:string
model user name:string user:references
In index.html.erb i'm trying to use <=% User.where(group:"Admins) %> and then return on localhost/users (address in RAM i guess) - #<Project:0x007f6f38594af8>. How can i get just name of user where category is Admins?
UPD: I need to list all users of "Admins" group.

Yes, Clear your question. You cannot do <=% User.where(group:"Admins") %> because Group is a model.
But you can scope in Model which will give you list of all users of "Admins" group
class User < ActiveRecord::Base
scope :admin_groups, -> {includes(:groups).where(groups: { title: 'Admin') } }
end
In your view You can call <%= User.admin_groups %>.
Hope this is helpful.

Related

Rails: Using Controller as a Model Name

I have a model that is called "controller". I checked the rails reserved terms list and it does not show "controller" as a word not to be used.
The model works fine but when I use the model in a view, the view does not submit the controller attribute back to the controller.
Any idea if "controller" is in fact a reserved word?
Yes controller is reserved in RoR. Even you can use it like this in your views:
#to get controller name:
<%= controller.controller_name %>
#to get action name, it is the method:
<%= controller.action_name %>

Rails 4: chaining associated objects in Views

Ok, I searched all over the web and found no answer.
I am looking for a way to display a name of a 'category' in the show view of a post (I have to mention I'm rookie in Rails).
I have....
a model "Post"
class Post < ActiveRecord::Base
has_many :categories
belongs_to :user
end
a model "Category"
class Category < ActiveRecord::Base
belongs_to :post
end
and the "show" view of the "post" has a line like this
<%= #post.category.name %>
The error message as screen shot:
NoMethodError in Posts#Show - undefined method `category' for #
The "show" action in "Posts" controller:
def show
#post = Post.find(params[:id])
end
I'm building this app along a little outdated training video on udemy. In this video there's in the category model a line with "attr_accessible"
class Category < ActiveRecord::Base
attr_accessible :name <---------------------- this
has_many :posts
end
...but this does no longer exists since Rails 4.0. Is there another way to retrieve the category name of the post?
Thank you in advance :-)
I got the answer. I found out, that every way, to get the data out of the table categories in the view for products won't work. I than thougt, showing the category in the category show view is simple working. With this idea in mind I took the same code, this one:
app/views/categories/show.html.erb
<p>
<strong>Name:</strong>
<%= #category.category_name %> <--------this line
</p>
...from the category show view and put it into the post show view. I than got again an error but different:
--> NoMethodError in Posts#show
Ok, this says the instance variable "#category" isn't available for the post show view. To change that was easy. I copied the object from the categories controller's show action into the posts controller's the show action. Like this:
class PostsController < ApllicationController
.
.
.
def show
#post = Post.find(params[:id])
#category = Category.find(params[:id])
end
And: it works!!!!
But now, is there something wrong to do it like this?
Cheers.
The method category not exists because the Post model has many "categories" not one "category". The Post should have the method "categories". Then if you want to show a first "category" of post in the view:
<%= #post.categories.first.name %>
If you want to show all "categories" of post, then you iterate the collection:
<% #post.categories.each do |category| %>
<%= category.name %>
<% end %>
I tried again and found the real error in my code. the foreign key was not set by Rails. I had to do manually. The table which has a "belongs_to" (in my case the posts table) needs a foreign key added (like category_id).
First creating the migration file:
rails g migration add_foreign_key_to_posts_table
Second adding the migration code to the migration file:
class AddForeignKeyToPostsTable < ActiveRecord::Migration
def change
add_foreign_key :posts, :categories
end
end
Third raking the db migration with:
rake db:migrate
Fourth adding the foreign key for other resources by following steps one to three. Now everything works fine.

Rails 4 - Update Join Table Attributes with has_many through

This is a follow-up of my question: Rails 4 - Access Join Table Value in views
Now I know how to retrieve join table attributes and show them in view. But still I can't find the right approach to edit and update the attribute.
Models:
class Recipe < ActiveRecord::Base
has_many :recipe_ingredients
has_many :ingredients, through: :recipe_ingredients
end
class Ingredient < ActiveRecord::Base
has_many :recipe_ingredients
has_many :recipes, through: :recipe_ingredients
end
class RecipeIngredient < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
#there is an attribute t.text :amount
end
Recipe#Edit:
...
<%= simple_form_for #recipe do |f| %>
<div class="form-group">
<%= f.input :name, input_html: { class: "form-control"} %>
<%= f.input :description, input_html: { class: "form-control"} %>
<%= f.collection_select(:ingredient_ids, Ingredient.all, :id, :title, {}, {multiple: true}) %>
<!-- reserve for recipe_ingredients.amount -->
</div>
<%= f.submit "Submit", disable_with: 'Submitting...', class: "btn btn-primary"%>
<% end %>
...
As shown above, this is a many-to-many relationship, each recipe may have several ingredients. It works fine and I can choose the right models to associate with (using collection_select). But I have left the work to edit and update join table attributes undone. I have two ideas in my mind:
Make another edit page for editing join model attributes
Ajax? But not quite familiar with
I know the question seems to be trivial, but many solutions are out-dated(Rails 3). Desperate for a Rails 4 solution.
Edit
Intention: I would like to make the creation of Recipe and Ingredient models on their own, which is done. User will see which recipe using the ingredient in Ingredient#show action, which is done also. As to Recipe#show action, there is a slight difference, where user will see which ingredient it is using as well as the amount(join table attribute), which is done in my previous question. The last problem is, I would like to make this attribute editable.
You may want to look into doing nested models combined with the cocoon gem. This will allow you to have a form which updates multiple models at once and it takes care of all the ajax for you. https://github.com/nathanvda/cocoon. I used this gem on a system where the user needed to be able to add one or more answers to a trivia question via dynamic form fields. I think it could work for you as well with giving the user the ability to add one or many RecipeIngredient relations for a recipe. You would be able to add selects dynamically to your form via Cocoon containing a select with the Ingredient model records.

Rails Cocoon Delete/Destroy Single Instance

I am using Cocoon gem to associate resume fields to one resume, and each user has ONE resume and have everything working the correct way via cocoon documentation. However, I would like the ability for users to be able to edit resume fields/nested models directly on the profile page without being redirected to the cocoon nested form page. Further more I would like users to have the ability to add and or delete a SINGLE field/entry. Is there any way at all to accomplish this?
In my console I have been able to successfully delete an entire resume nested model using
User.last.resume.resume_edus.destroy_all
Where 'resume.edus' is the nested model inside of resume complete with 3 other 'text_fields'. But as stated I would only like to be able to edit/delete a single instance of resume_edus. Any ideas?
User.rb
has_one :profile
has_one :resume
Resume.rb
belongs_to :user
has_many :resume_edus
accepts_nested_attributes_for :resume_edus,
reject_if: :all_blank,
allow_destroy: true
Resume_edu
belongs_to :resume
Resume Controller
params.require(:resume).permit(:user_id, :cover,
resume_edus_attributes:
[:id, :title, :date, :description, :_destroy])
Figured out the answer! I passed the resume_edus 'ID' in the delete action
<%= link_to "Delete", resume_path(r.id), method: :delete %>
Then was able to search for said ID in the current users resume_edu modal to specifically isolate and delete it without deleting the other instances of the model!
def destroy
#instance = current_user.resume.resume_edus.find(params[:id])
debugger
#instance.destroy
flash[:notice] = "Resume Field Was Deleted"
redirect_to profile_path(current_user)
end
accepts_nested_attributes_for :order_line_items, allow_destroy: true
<tr class="nested-fields">
<%= f.hidden_field :_destroy %>
<%= link_to_remove_association "Delete", f %>
</tr>
Add _destroy in controller params:
order_line_items_attributes: %i[id product_id quantity price discount total _destroy]

Updating Roles in rolify using ActiveAdmin

Using Rails 4.0, ActiveAdmin, Rolify and CanCan, Adding and removing user roles via the activeadmin panel does not save (commit to database).
The my ActiveAdmin User and User Model look okay as I can list all the roles that apply to a user using check_boxes. Although when adding any roles or removing any roles via the checkboxes the changes do not get applied.
I get a notification that the user was updated successfully but as I look through the database or render the page, the roles have not been updated.
How can I get the roles to update when the form is saved?
Edit:
Using Devise also.
The solution here is to allow the ActiveAdmin controller to update the role ids related to the user.
ActiveAdmin.register User do
permit_params :email, :password, :password_confirmation, role_ids: []
Here's a form that shows a check box for each global role.
form do |f|
f.inputs "User Details" do
f.input :email
f.input :password
f.input :password_confirmation
f.input :roles, as: :check_boxes
end
f.actions
end
While we're at it, we might as well make it possible to update the user without entering their password:
# Allow form to be submitted without a password
controller do
def update
if params[:user][:password].blank?
params[:user].delete "password"
params[:user].delete "password_confirmation"
end
super
end
end
Put all of this in the app/admin/user.rb.
I just ran into this issue. The problem was with validation of presence (which I think is occurring in the database ":null => :false"). In order for the update to save, I had to fill out all fields (including password/password confirmation).
I had to add some controller code to make this work, I hope this helps:
Remember to permit the attributes you're accepting in active_admin as such (this will create the permitted_params method I'll be referring to in a bit.
Note that since we're not saving role_ids directly to the user, it doesn't even have to be a permitted param.
permit_params :email, :password, :etc
Create a private method we could call from the create and update controllers. This method will just iterate over non-empty ids, find the associated roles, and add them to user.roles.
The create and update methods simply find call the add_roles method prior to continuing execution. ActiveAdmin makes the the existing user available through resource, but not through create. We have to find it ourselves in create!
controller do
def create
#user = User.new(permitted_params[:user])
add_roles(#user)
create!
end
def update
add_roles(resource)
update!
end
private
def add_roles(resource)
resource.roles = []
params[:user][:role_ids].each { |r| resource.roles.push(Role.find(r)) unless r.blank? }
end
end
In the activeadmin form, you can add:
form do |f|
# other inputs
f.input :roles, as: :select, multiple: true, collection: Role.all
end
And in the show page, you can display the roles as such:
show do
attributes_table do
# other rows
row :roles do |r|
r.roles.map { |role| role.name }.join(", ")
end
end
Hope this helps!