Rails - Get 3 ID's in a form - ruby-on-rails

I have a group#view page, that is accessed by a Person. In this page, the Person can see the members of the group via methods I developed. The problem is that I need to create the model Honors using the Id from the group, the id from the person accessing the page, and the id from a member of this group.
In my Honors controller I have:
def create
#person = Person.find(current_person)
#honor = Honor.create(:group => Group.find(params[:group_id]),
:person => Person.find(current_person), :honored => Person.find(current_person))
if #honor.save
...
end
The problem is in this :honored => Person.find(current_person), that is not getting the right ID and I don`t know how to get it.
In my view:
<% #asked_groupmembership.each do |agm| %>
<% form_for(:honor, :url => honors_path(:group_id => #group.id, :person => current_person.id,:honor => agm.member.id)) do |f| %>
Any help?
Thanks.

If you need 3 components to properly create an honor record, you need to pass them from the form. You seem to be doing that part correctly.
:group_id => #group.id
:person => current_person.id
:honor => agm.member.id
To create the record, access the passed variables.
Honor.create(:group => Group.find(params[:group_id]),
:person => Person.find(params[:person]),
:honored => Person.find(params[:honor]))
Understanding the above isn't the most efficient, but used for demonstrative purposes. You'd likely want to avoid redundant database hits, e.g. :person => current_person rather than another query

Related

Activerecord-reputation-system - how to check value of current_user's vote

I'm checking if a user has voted on a given post and then changing the up and down arrows' styling. The activerecord-reputation-system gem hasn't been updated in a while and every example I find either uses outdated code or requires tracking "up" votes and "down" votes separately. I prefer to just use :post_votes and check the value of that one parameter.
posts_controller.rb
#voted_items = Post.evaluated_by(:post_votes, current_user)
index.html.erb
<% if current_user && #voted_items.include?(post) %>
# display active up or down arrows
<% end %>
How do I get just the value of the relevant record within the #voted_items object?
Edit: I notice there is no built-in scope for :value. Maybe adding one manually would let me query a particular value?
For now I am came up with this method def on the model:
def evaluation_value(user, comment)
if #up_voted = ReputationSystem::Evaluation.where(:reputation_name => "comment_votes",
:value => "1.0", :source_id => user.id, :source_type => user.class.name,
:target_id => comment.id, :target_type => comment.class.name).exists?
"upvoted"
elsif #down_voted = ReputationSystem::Evaluation.where(:reputation_name => "comment_votes",
:value => "-1.0", :source_id => user.id, :source_type => user.class.name,
:target_id => comment.id, :target_type => comment.class.name).exists?
"downvoted"
else
nil
end
end
It's not ideal because it requires hardcoding the values and other details, but it works for now until the gem is updated to allow checking individual values.
This way I can run comment.evaluation_for(current_user, comment) == "upvoted" or downvoted.

Rails passing a list of objects to another controller with link_to_remote

Is it possible to pass a list of objects to another controller in Ruby on Rails?
I have experimented with the following example:
class Student
...
end
student_list = [std1, std2, ... stdn]
When I use
<%= link_to_remote("example", :url => {:controller => 'class/assignment',
:action => 'homework',
:student => student_list})%>
It did not work the way I expected. params[:student] is equal to "student" (string literal).
Is there anything I did wrong, or an alternate way of doing it?

Passing IDs through a new Form

This question is about a different approach I'm trying to the one asked here:
Passing IDs through a new Form
I have a group#view page, that is accessed by a Person. In this page, the Person can see the members of the group via methods I developed. The problem is that I need to create the model Honors using the Id from the group, the id from the person accessing the page, and the id from a member of this group.
In my Honors controller I have:
def create
#person = Person.find(current_person)
#asked_groupmembership = #person.owned_group_memberships.find_all_by_status(true,:include => [:group, :member])
#asked_groupmembership.each do |agm|
#honor = Honor.create(:group => Group.find(params[:group_id]),
:person => Person.find(current_person), :honored => Person.find(agm.member.id))
end
if #honor.save
...
end
In my view I have a link that directs the person to the form in order to create a new honor:
<% #asked_groupmembership.each do |agm| %>
<%= link_to "Create Honor", new_honor_path(:group_id => #group.id, :person => current_person.id,
:honored => agm.member.id) %>
But in my forms I can't get the ids and stuff
<% form_for(:honor, :url => honors_path(:group_id, :person,
:honored)) do |f| %>
The error I get is that I can't find Group without an Id.
Any ideas? Thanks.
##Edited2##
Changed my crontroller
def new
##person = Person.find(params[:person])
##honored = Person.find(params[:honored])
##group = Group.find(params[:group_id])
#honor = Honor.new
end
def create
#person = Person.find(current_person)
#honor = Honor.create(:group => Group.find(params[:group_id]),
:person => Person.find(params[:person]),
:honored => Person.find(params[:honored]))
if #honor.save
...
end
First, it seems like you are missing a controller method. Along with every form that creates a new object there are typically two controller methods
new
Gathers up any data that the form needs to render itself
Renders the form
create
Collects the data from the form
Creates the new object
It looks to me like you are missing the new method. In the new method you would gather up all the hidden data that the form needs (e.g. the information that the user is not going to type in directly, like the #person info). Then, I would put this information in your form using hidden form parameters (rather then trying to put it in the form URL).
Objective: From the group#view, loop through and create and "Add Honor" link for each member of the group, while keeping track of the specific member being honored, group in which said member is honored, and the person who is honoring.
The following accomplishes that objective.
Route:
match "honors/:group/:person/:honored" => "honors#create", :as=>"my_custom_new_honor"
Group view:
<% #asked_groupmembership.each do |agm| %>
<%= link_to "Create Honor", my_custom_new_honor_path(:group=> #group.id, :person => current_person.id,:honored => agm.member.id) %>
Honor Controller, Create Method
#honor = Honor.create(:group => Group.find(params[:group_id]),
:person => Person.find(params[:person]),
:honored => Person.find(params[:honored]))
In this scenario you do not need the honor#new method, you're going directly to the create method. This assumes all the relationships are established correctly.

How can I retrieve information from an active record with collection select?

I have 3 models (Users - Membership - Community)
The users can become members to many communities. For this I made a Membership that contain the user_id, community_id.
After connected, the user have to choose a community. The model User as a community_id that contain that unique community.
When editing, he would be able to change this community.
If I do this :
<%= f.collection_select :community_id, Community.find(:all), :id, :name, { :allow_blank => 'Select a community' }, :style => "width: 200px;" %>
All the communities happier, also that who he is not member.
I tried this :
<%= f.collection_select :community_id, Membership.find(:all), :community_id, :id, { :allow_blank => 'Select a community' }, :style => "width: 200px;" %>
But I show only the number (:id) of the Membership…
How can I join this id with the name of the community ?
Not sure if this will work but try it out:
member.rb # add a method to the member model that returns the
def community_name
community.name
end
#view
<%= f.collection_select :community_id, Membership.find(:all, :include => :community), :community_id, :community_name, { :allow_blank => 'Select a community' } %>
The :include option prefetches all communities in the membership collection in one query.
I think you were closer with your first attempt but instead of finding all communities you need to just find communities that the user is a member of. So instead of Community.find(:all) you would use:
Community.find(:all,
:includes => :memberships,
:conditions => ['memberships.user_id = ?', #user.id])
This assumes that you have an #user variable set up for your view. You need this to restrict the find to just communities that your user is a member of.
It also assumes that there's an association on Community: has_many :memberships. I've guessed you've got that already from the question.

Creating a new nested resource

I'm working on a basic garden logging application which consists of gardens, plants and planted plants. Each user has one or many gardens, plants are master definitions, and a planted plant can be thought of as an instance of a plant in a specific user's garden.
In my routes.rb file I have the following:
map.resources :gardens do |gardens|
gardens.resources :planted_plants, :has_many => :plant_log_entries, :collection => { :filter => :post, :choose_garden => :post}
gardens.resources :garden_log_entries
end
map.resources :plants
This makes sense to me when retrieving a list of planted_plants in a user's garden, but I'd like to create a planted_plant record from the index of plant. The problem is, a user can have multiple gardens. How can I create a new form for a planted_plant that allows the user to specify which garden should be used?
The current route requires a garden_id - which makes sense for retrieval, but I'd like to supply that as a parameter for creation.
Thanks in advance for any help!
I would add another (non-nested) route, to allow access to the PlantedPlantsController#create action without specifying the garden_id in the URL:
map.resources :planted_plants, :only => :create
This will allow you to post your form to /planted_plants. As for the form itself, you'll probably need something like this:
<% form_for #planted_plant do |p| %>
<%=p.label "garden_id", "Garden" %>
<%=p.collection_select :garden_id, current_user.gardens, :id, :name %>
... other fields ...
<% end %>

Resources