Closed boberetezeke closed 11 years ago
The error is specific about what its complaint is. I'm still on the fence as to whether this should work but here's what I think right now: MotionModel was written before define_method worked. That's a game-changer, and will eliminate a lot of the method_missing voodoo while at the same time improving efficiency and making the code clearer. Given that the code will need to be revisited for that -- and soon -- I'd propose not making this spec pass for right now.
That said, I've included my spec for the same thing below. I tried to separate out the expectations in a very granular manner to make certain I knew where the failure is. I still don't have it passing (sigh).
Here are a couple of other random thoughts:
Done with randomness. Please let me know whether you think my roadmap (switch to define_method first) makes sense or if this is a deal-breaker misfeature.
Steve
describe "supporting belongs_to" do before do Task.delete_all Assignee.delete_all end
it "allows a child to back-reference its parent" do
t = Task.create(:name => "Walk the Dog")
t.assignees.create(:assignee_name => "Rihanna")
Assignee.first.task.name.should == "Walk the Dog"
end
describe "mind changing behavior in belongs_to" do
before do
@t1 = Task.create(:name => "Walk the Dog")
@t2 = Task.create :name => "Feed the cat"
@a1 = Assignee.create :assignee_name => "Jim"
end
describe "basic wiring" do
before do
@t1.assignees << @a1
end
it "pushing a created assignee gives a task count of 1" do
@t1.assignees.count.should == 1
end
it "pushing a created assignee gives a cascaded assignee name" do
@t1.assignees.first.assignee_name.should == "Jim"
end
it "pushing a created assignee enables back-referencing a task" do
@a1.task.name.should == "Walk the Dog"
end
end
describe "when pushing assignees onto two different tasks" do
before do
Debug.resume
@t2.assignees << @a1
Debug.silence
end
it "pushing assignees to two different tasks lets the last task have the assignee (count)" do
@t2.assignees.count.should == 1
end
it "pushing assignees to two different tasks removes the assignee from the first task (count)" do
@t1.assignees.count.should == 0
end
it "pushing assignees to two different tasks lets the last task have the assignee (assignee name)" do
@t2.assignees.first.assignee_name.should == "Jim"
end
it "pushing assignees to two different tasks lets the last task have the assignee (back reference)" do
@a1.task.name.should == "Feed the cat"
end
end
end
end
On Oct 25, 2012, at 6:08 PM, Steve Tuckner notifications@github.com wrote:
Adding these two tests to the end of spec/relation_spec.rb causes an error in the second one. I am not sure if the first test is even supposed to pass (but I would like both to work actually).
describe "supporting belongs_to by assignment" do before do Task.delete_all Assignee.delete_all end
it "allows a child to back-reference its parent" do t = Task.create(:name => "Walk the Dog") a = Assignee.create(:assignee_name => "Rihanna") a.task = t Assignee.first.task.name.should == "Walk the Dog" end
end
describe "supporting belongs_to by assignment with two objects" do before do Task.delete_all Assignee.delete_all end
it "allows a child to back-reference its parent" do t = Task.create(:name => "Walk the Dog") a1 = Assignee.create(:assignee_name => "Rihanna") a2 = Assignee.create(:assignee_name => "Madonna") a1.task = t Assignee.all[0].task.name.should == "Walk the Dog" a2.task = t Assignee.all[1].task.name.should == "Walk the Dog" end
end
The error is:
ArgumentError: type task : belongs_to is not possible to cast. model.rb:325:in cast_to_type:': supporting belongs_to by assignment - allows a child to back-reference its parent model.rb:437:inmethod_missing:' spec.rb:183:in block in run_spec_block' spec.rb:307:inexecute_block' spec.rb:183:in run_spec_block' spec.rb:198:inrun'
— Reply to this email directly or view it on GitHub.
The reason that I was hoping this would work was that I want to take a parsed JSON string that gives data like
[ {"name" => "walk the dog", "assignees" => [{"assignee_name" => "Bob"}]}, {"name" => "feed the cat", "assignees" => [{"assignee_name" => "Fred"}]}, {"name" => "do nothing"} ]
And use that data to do the following:
data.each do |task_data| Task.create(task_data) end
So that we end up with three tasks, and two assignees with the first two tasks referencing their assignees.
Task.count == 3 Assignee.count == 2
I guess this does not apply to this issue because in this case, I am assigning to a has_many (:assignees) instead of a belongs_to. I guess I came across the belongs_to case by just playing in the REPL and was surprised that it sometimes worked and other times didn't. I think that the times it worked work just by accident and not by design.
All that said, the standard model for web apps is that the server (ie. rails) creates an object graph with child objects that it renders in HTML for the browser and then that gets submitted back to the server (with possible modified/deleted/created parts of the object graph). That is minimally what I would like to do with MotionModel:
Maybe I am just looking at this wrongly. :-(
I guess what I am looking for is the following
class Task include MotionModel::Model
columns :name => :string has_many :assignees
accepts_nested_attributes_for :assignees end
Task.find(id).update_attributes(json_data)
I am willing to work on this part, but am not sure if you feel it is a good idea or where something like this should be implemented.
I'm going to close this as fixed, even though I didn't implement the accepts_nested_attributes_for. If you want to think through initializing an object graph from JSON, which is, I guess, what accepts_nested_attributes_for would do, feel free to fork this and have a go at it.
Adding these two tests to the end of spec/relation_spec.rb causes an error in the second one. I am not sure if the first test is even supposed to pass (but I would like both to work actually).
describe "supporting belongs_to by assignment" do before do Task.delete_all Assignee.delete_all end
end
describe "supporting belongs_to by assignment with two objects" do before do Task.delete_all Assignee.delete_all end
end
The error is:
ArgumentError: type task : belongs_to is not possible to cast. model.rb:325:in
cast_to_type:': supporting belongs_to by assignment - allows a child to back-reference its parent model.rb:437:in
method_missing:' spec.rb:183:inblock in run_spec_block' spec.rb:307:in
execute_block' spec.rb:183:inrun_spec_block' spec.rb:198:in
run'