I have a join table, which have 3 parameters. I want to update it, using a where-clause, something like this: (which obviously is not correct)
Grid.update(:page_id => #page_id,:thing_id => #thing_id,:number => #number ).where(:page_id => #page_id, :number => #number ).first
I need to find the record with mathing page_id and number, and then update the thing_id.
Thanks!
Jakob
Grid.where(:page_id => #page_id, :number => #number).first.
update_attributes(:page_id => ...,: thing_id => ..., :number => ...)
Related
I'm successfully following some of the commands listed here and applying them to my own tables.
How do I turn the output into actual records/data ? Presently it's returning some output which I can assign to a variable, but I do not understand this output at all.. it doesn't look like an array or hash (but perhaps it is), and I do not understand how to access its contents (I want to use the output in a rails view, but at the least would like to access the table records in the console where I'm executing the Arel code)
For example, say I have two tables; User and Product as follows:
User = [{:id => 1, :name => "Joe", :email => "joe#gmail.com"}, {:id => 2, :name => "Jane", :email => "jane#gmail.com"}]
Product = [{:product_name => "Car Tire", :brand => "BMW", :last_edited_by => 1}, {:product_name => "Paint Brush", :brand => "Dulux", :last_edited_by => nil}, {:product_name => "Dog Biscuits", :brand => "Bowow Snacks", :last_edited_by => 2}, {:product_name => "Game", :brand => "Westwood", :last_edited_by => 1}]
Suppose I want to join the two tables User.id = Product.last_edited_by
In SQL it would be as simple as:
SELECT *
FROM User
JOIN Product
WHERE users.id = products.last_edited_by
Now if I plug this into scuttle.io to convert to Arel, it gives:
User.select(Arel.star).where(
User.arel_table[:id].eq(Product.arel_table[:last_edited_by])
).joins(
User.arel_table.join(Product.arel_table).on(null).join_sources
)
But trying this returns: ArgumentError: wrong number of arguments (given 1, expected 0)
Attempting to emulate advice given here, I come up with another approach:
users.project(Arel.star).join(User).on(Product[:last_edited_by].eq(User[:id]))
But this returns: NoMethodError: undefined method `project' for Array..
A final point, if I run
users = Arel::Table.new(User)
output = users.project(users[:id].as("id"), users[:id].count.as("count")).group("id")
I get some output which looks almost meaningful, but I don't know how to return that into something I can make sense of, and I wouldn't know how to use it if I provided it to a rails view
Firstly, I'm really sorry to ask such a basic question but I'm very new to Rails, Ruby & development in general and my lack of terminology understanding means that I am having a hard time finding the answer to this question.
I am importing a csv of vehicle data using:
def self.import(file, category_id)
CSV.foreach(file.path, headers: true) do |row|
Model.where(
:category_id => category_id,
:name => row[1],
:cap_id => row[10]
).first_or_create do |record|
record.layout = row[3],
... several records later ...
record.manufacturer_id = Manufacturer.where(:name => row[0], :category_id => category_id).id
end
end
end
but I am having trouble setting the manufacturer_id with the last line of the loop. I guess you can see what i'm trying to do here but I can't work out how this should be written.
Basically i have a list of manufacturers belonging to different categories (so, for example, there is a Ford manufacturer with category_id=1 (for cars) and another Ford manufacturer with category_id=54 for trucks.
Can I set the manufacturer_id of each record by taking the current category_id and the manufacturer name from the csv, cross referencing them and pulling back the id of the result?
When trying the above code i get the following error:
NoMethodError in ModelsController#import
undefined method `id' for #<ActiveRecord::Relation::ActiveRecord_Relation_Manufacturer:0x007fcd96f744a8>
Extracted source (around line #33):
32 record.description = row[2],
33 record.manufacturer_id = Manufacturer.where(:name => row[0], :category_id => category_id).id
34 end
35 end
36 end
The following line of code returns an ActiveRecord::Relation object
Manufacturer.where(:name => row[0], :category_id => category_id)
so when you called id on it, it raised an error. You should call first first and then id.
Manufacturer.where(:name => row[0], :category_id => category_id).first.id
Be warned that doing so assumes that you'll always get a manufacturer that matches the condition. To be more safe, you can use try
Manufacturer.where(:name => row[0], :category_id => category_id).first.try(:id)
This is just a simple question. I was trying to create a new object in Rails by passing in parameters to the constructor. However, when I execute the code, I get
SQLite3::SQLException: no such column: awards.user_id: SELECT "awards".* FROM "awards" WHERE "awards"."user_id" = 1
which means the object isn't being constructed properly. Should I be using create instead of new? That isn't working either.
def refresh_awards(user)
new_awards = []
if (user.karma < 40 ) #test award
a = Award.new(:name => "Nobody Award", :description => "From Jonathan", :category => "Community", :value => 1337, :level => 0, :handle => "nobody_award")
user.awards.append(a)
new_awards.append(a)
end
new_awards.each do |a|
flash[:notice] = "You received the " + a.name + "!"
end
end
Have you add has_many :awards to the User model? Have you added belongs_to :user to the Award model? Have you added the column user_id to the Award model (using a migration)? You'll need to do these three things to be able to use the user.awards method you're using. Read the Rails Guide on Associations for more detail.
Also, append isn't a Ruby method - the closest method would be <<. You would use it like this:
a = Award.new(:name => "Nobody Award", :description => "From Jonathan", :category => "Community", :value => 1337, :level => 0, :handle => "nobody_award")
user.awards << a
But you could neaten this into one line of code using the create method:
a = user.awards.create(:name => "Nobody Award", :description => "From Jonathan", :category => "Community", :value => 1337, :level => 0, :handle => "nobody_award")
EDIT: To create the user_id column in the Award model, run the following code from terminal (while in your app's directory):
rails generate migration AddUserIdToAward user_id:integer
rake db:migrate
I have some trouble with mongoid:
test "Test candidate" do
User.create(:id => 1, :sex => User::Male, :country => 1, :city => 1)
User.create(:id => 2, :sex => User::Female, :country => 1, :city => 1)
User.create(:id => 3, :sex => User::Female, :country => 1, :city => 1)
user = User.not_in(:id => [2]).second
assert_not_equal(user.id, 2)
end
Test failed. I've tried to use where(:id => {'$nid' => [2]}), but it have same effect.
What is wrong? How to use "not in" condition with mongoid?
PS, "second" is ok, with "first" test passed, because id=1
Try this query:
user = User.not_in(:_id => [2]).second
In MongoDB primary key has name _id. Mongoid tries to be friendly and partially hides this fact from the developer by aliasing it to id in the object model. But when you do queries, it cannot tell if you want primary key _id or some completely ordinary field id.
user = User.where(:id.nin => [2,3,4,5])
This is as per mongoid official doc : http://mongoid.org/en/origin/docs/selection.html
modules=MenuModule.all(:order => "module_seq")
modules.each do |m|
groups=m.menu_groups.all(:order => "group_seq")
groups.each do |g|
items=g.menu_items.all(:order => "item_seq")
items.each do |i|
puts i.name
end
end
end
UPDATE
How to use include with order ?
Something like MenuModule.find(:all,:include => {:menu_groups(:order => "group_seq"), :menu_items(:order => "item_seq")},:order => "module_seq")
Is it possible ?
See: http://www.arraystudio.com/as-workshop/nested-include-activerecord-option.html
MenuModule.all(:include => [{:menu_groups, :menu_items}], :order => 'module_seq,modules.group_seq,modules.groups.item_seq')
If the item_seq is not what you want to sort on, you probably can sort using the ruby sort method. The mysql order clause in a nested join only will order by one constrain in the join, as far as I am aware.