How do you compare variables from different tables with ruby on rails? - database

For example, within a model/data-set/table (technical term?) called "microposts" if I have id and user_id columns, to compare the two sets I can use
Micropost.where("user_id = ?", id)
I am wondering, however, how to do the same thing with data from different data-sets/tables/models. In this particular scenario I am trying to find all instances where a user's community variable is equal to the community variable of any microposts. I'm attempting to match the content of the strings so that all microposts are rendered that have a community variable that matches the current user's community variable. These variables are in string form as #city + #state under the column "community" in the users's and microposts's model/datasets/table. Illustrated:
users table microposts table
user_id community micropost_id content community
1 FairfieldIowa 1 blub! FairfieldIowa
2 FairfieldIowa 2 Hiiy FairfieldIowa
3 Salt Lake CityUtah 3 wwowt! Salt Lake CityUtah
4 Salt Lake CityUtah 4 hey Salt Lake CityUtah
5 FairfieldIowa 5 sweet FairfieldIowa
I thought this might work in the User model:
def communityfeed
Micropost.where("community = ?", user.community)
end
However, it is incorrect because of syntax, logic, or because "user" does not define all users, I think.
Then I defined communityfeed_items in a pages_controller as:
def home
if logged_in?
#micropost = current_user.microposts.build
#communityfeed_items = communityfeed.paginate(page: params[:page])
end
end
But I get an undefined local variable or method communityfeed error
This could be because I'm not providing any user to use the method on. Perhaps simply using a variable for all users will solve my problem, but this is something I could not find. I've tried all_users, and user, with no success. Is it possible to compare variables to render a result in this way, and if so, what is the syntax to cycle through all user/microposts and check for these matches?
I also built several partials to function together to render the microposts, however, without the #communityfeed_items variable functioning correctly, they are of little use.
_communityfeed.html.erb
<% if #communityfeed_items.any? %>
<ol class="microposts">
<%= render partial: 'shared/communityfeed_item', collection: #communityfeed_items %>
</ol>
<%= will_paginate #communityfeed_items %>
<% end %>
_communityfeed_items.html.erb
<li id="<%= communityfeed_item.id %>">
<%= link_to gravatar_for(communityfeed_item.user), communityfeed_item.user %>
<span class="user">
<%= link_to communityfeed_item.user.name, communityfeed_item.user %>
</span>
<span class="content"><%= communityfeed_item.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(communityfeed_item.created_at) %> ago.
</span>
<% if current_user?(communityfeed_item.user) %>
<%= link_to "delete", communityfeed_item, method: :delete,
confirm: "You sure?",
title: communityfeed_item.content %>
<% end %>
</li>
If I have approached this problem in a severely inefficient/impossible way, I am open to suggestions.
Thanks for your time, generosity, and expertise.

Related

Why is Ruby array.each do not iterating over each item in array?

I'm new to ruby and rails and coding in general. But I'm working on a project that uses the steam web api to get a list of games owned by a user on steam. I'm trying to take that information and store it in my own table. I was able to get the information into my site but I need to select only one part of the information to pass into my table.
In my users controller I have this for show:
def show
#renders the user page
#user = User.find(params[:id])
#player = SteamWebApi::Player.new(#user.steam_id)
end
In the users show view I have this:
<% user_class = User.new %>
<h2> These are the games you own </h2>
<% #games = #player.owned_games %>
<% #steam_game_ids = user_class.get_steam_id_from_games(#games) %>
<br>
<%= user_class.check_if_games_exit_in_table(#steam_game_ids) %>
The #player.owned_games gives an array of games like this:
[{"appid" => 1234}, "something" => 23123}, {"appid" =>...}]
In my users model I define these methods:
def get_steam_id_from_games(games)
games.games.map{|x| x.values[0]}
end
def check_if_games_exist_in_table(steam_ids)
string_ids = steam_ids.map(&:to_s) #not converting to string
string_ids.each do |app_id|
if Game.exists?(game_app_id: app_id)
return "this exists"
else
return "#{app_id} doesn't exist"
end
end
end
get_steam_id_from_games makes an array with only the appid values for each game:[1234, 234545,..]
check_if_games_exist_in_table is supposed to take the appid array, converts the items to strings (that's how I store the information in my table), and then checks if there is an object in the table with the same appid.
This is where the problem is for me, the string_ids.each to |app_id| only goes through the first thing in the array. Is this because I'm returning "this exists" or "doesn't exist"? What can I do to fix this problem?
def check_if_games_exist_in_table(steam_ids)
string_ids = steam_ids.map(&:to_s) #not converting to string
array_of_non_existing_ids = []
string_ids.each do |app_id|
if !Game.exists?(game_app_id: app_id)
array_of_non_existing_ids.push app_id
end
end
return "#{array_of_non_existing_ids.join(',')} doesn't exist" if array_of_non_existing_ids.any?
return "this exists"
end

Print out collection as grouped items

So far I have a collection of programmes. A programme has an associated account and there are (currently) six different "types" of accounts that a programme can belong to.
I need to be able to dump out all the programmes but group them by the type of account they are.
Something like;
Alpha Type;
- Programme One
- Programme Two
- Programme Three
Beta Type;
- Programme Four
- Programme Five
Delta Type;
- Programme Six
So far all I have managed is to join the associated table and do an order by the account_type :name
<% #programmes.each do |programme| %>
<%= programme.account_type.name %>
<% end %>
Which will print out the programmes in a reasonable order but I don't know how to do the grouping.
I am using Postgres if that actually makes it easier? I am pretty new to both Ruby and Postgres
Actually seem to have cracked this one.
I stumbled over this post on Enumberable#group_by
Final code in the controller looks like this;
#programmes = "get all programmes.."
#account_names = #programmes.group_by{|programme| programme.account.name}
In the view I have;
<% #account_names.each_pair do |name, programmes| %>
<hr>
<strong><%= name %> programmes</strong>
<br>
<% programmes.each do |programme| %>
<i><%= programme.name %></i><br>
<% end %>
<% end %>
Remarkable!

Rails 4.1.4 ActionController param is missing or the value is empty: name

I am relatively new to learning how to code and I am really having problems understanding how to write the code for dealing with parameters in a private method in the controller of a Rails 4.1.4 app so that my app works correctly by allowing me to enter a new picture album name, save it to the db, and have it be persisted so that the name of the new album added shows correctly (currently, it does not work right at all). Can someone please help me? Any help at all would be greatly appreciated.
Here is my code for my albums controller:
class AlbumsController < ApplicationController
def index
#albums = Album.all
end
def new
#album = Album.new
end
def create
#album = Album.new(album_params)
#album.save
redirect_to albums_path
end
def show
#album = Album.find(params[:id])
end
def edit
end
def update
end
private
def album_params
params.require(:name).permit(:id, :category)
end
end
Also, here is my album model:
class Album < ActiveRecord::Base
belongs_to :user
has_many :photos
end
And here is my migration for the albums:
class CreateAlbums < ActiveRecord::Migration
def change
create_table :albums do |t|
t.string :name # Column for album name of type string
t.string :category # Column for photography category of type string
t.timestamps
end
end
end
Here is my code for my app/views/albums/index.html.erb file:
<div><%= link_to "Admin Access to Add New Album", new_album_path %></div>
<div><%= link_to "Home", root_path %></div>
<h1>Albums Gallery</h1>
<% #albums.each do |album| %>
<div><%= link_to album.name, "/albums/#{album.id}" %></div>
<% end %>
Here is my code from my app/views/albums/new.html.erb file where I use the form_for thing:
<h2>New Albums</h2>
<%= link_to "Back", albums_path %>
<%= form_for (#album) do |f| %>
<div>
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<%= f.submit "Add Album" %>
<% end %>
Everything up to the form_for part where I try to enter a new picture album name works. It's at this point where everything just unravels and won't work for me. Instead of accepting and then showing the new album by name, it displays "/albums/3" when it should display "Nature Scenes". I went into my rails console to see what was going on on the db level and the new albums are not being created and saved correctly. My output from the Rails console looks like this:
2.1.2 :007 > Album.all Album Load (0.2ms) SELECT "albums".* FROM "albums" => #, #, #,
, #
nil, category: nil, created_at: "2014-09-21 02:50:54", updated_at:
"2014-09-21 02:50:54">]>
2.1.2 :008 >
(Sorry about the copy/paste, but being too new at trying to learn how to code, I don't have enough reputation points on Stackoverflow to be allowed to simply post a screenshot yet.)
OK, never mind, I got it. I had the wrong value in the private method. I changed it to
def album_params
params.require(:album).permit(:id,:name, :category)
end
And now the app works fine (at least, so far - I have a long way to go to complete it).

How to update a nested collection_check_box

I have a form for a child (categorization) nested within the parent form (project). The categorization attributes are created using a collection_check_boxes helper like so:
<%= f.fields_for :categorizations do |cat| %>
<%= collection_check_boxes :categorization, :category_id, #categories, :id, :display_name %>
<% end %>
In the Projects controller I'm able to successfully create the new records:
def create
#project = Project.new(project_params)
valid_categorizations = params[:categorization][:category_id].reject! { |c| c.empty?}
#project.categorizations.build(valid_categorizations.map{|cat| {category_id: cat}})
...
end
...
def project_params
params.require(:project).permit(:slug, :title, :body, :published, :category_ids => [])
end
Now, when I want to edit the parent Project record the collection_check_boxes does two undesirable things:
It does not pre-populate attributes (like the .include?(attribute) in a traditional check box), and
It repeats the set of check boxes N times depending on how many categorization records exist in the database (e.g., if Project #1 has three Categorization records the entire set of check boxes will display three times in the edit form).
I can't figure out how to fix this, so any help is greatly appreciated!

Rails 4 : basic use of Merit gem with Devise

Using the merit gem, I want to create a Pioneer badge for the first 100 users of my app.
The code in merit.rb
Merit::Badge.create!(
id: 1,
name: 'Pioneer',
description: "Belongs to the 100 first users of the site",
image: '/images/pioneer.png'
)
The code from badges_rules.rb takes in consideration that i'm using devise for authentification. So I followed this how to.
grant_on 'users/registrations#create', badge: 'Pioneer', model_name: 'User' do |user|
user.id < 101
end
It's not creating any badge. It's interesting to notice that this other badge is working very well :
grant_on 'users/registrations#create', badge: 'Inscription', model_name: 'User'
It seems that Devise is messing with the user object. I did override the registration controller, exactly like the Howto said. And when I call this controller in a simple way, like with this "Inscription" badge, everything's ok.
But when I need to put a condition on the user's id, nothing happens.
For information, this is the code from user's show view, where the badges are displayed (this is working).
<% #user.badges.first(5).each do |b| %>
<%= image_tag(b.image) %>
<%= b.name %>
<%end%>
Add model_name: 'User' to your rule. This happens when the controller name is not named after the object (registrations != user).

Resources