New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How update 'belongs_to' value? #1476

Open
vasiliyaltunin opened this Issue Nov 28, 2018 · 3 comments

Comments

Projects
None yet
1 participant
@vasiliyaltunin

vasiliyaltunin commented Nov 28, 2018

I have parent model

type TestList struct {
	ID        int       `json:"id" db:"id"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
	Name      string    `json:"name" db:"name"`
	Descr     string    `json:"descr" db:"descr"`
	Author    string    `json:"author" db:"author"`
}

and child model

type TestQuestion struct {
	ID        int       `json:"id" db:"id"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
	Question  string    `json:"question" db:"question"`
	Weight    float64   `json:"weight" db:"weight"`
	Parent    TestList  `belongs_to:"test_list" fk_id:"ID" primary_id:"ID"`
}

all seems work fine, i use Eager() to load info from parent, but i have problem with saving.

To choose parent value i use

<%= f.SelectTag("Parent",{options: listmap}) %>

n template, that converts to

<select class=" form-control" id="test-question-Parent" name="Parent"><option value="2">123</option><option value="3">789</option><option value="1">456</option></select>

so it looks just fine, but when i save form in console i get

UPDATE test_questions SET question = :question, updated_at = :updated_at, weight = :weight WHERE test_questions.id = :id
it seems buffalo just ignore Parent field and did not update it,

here my update method

// Update changes a TestQuestion in the DB. This function is mapped to
// the path PUT /test_questions/{test_question_id}
func (v TestQuestionsResource) Update(c buffalo.Context) error {
	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	// Allocate an empty TestQuestion
	testQuestion := &models.TestQuestion{}

	if err := tx.Eager().Find(testQuestion, c.Param("test_question_id")); err != nil {
		return c.Error(404, err)
	}

	println("===")
	println("parent from get: ")
	println(c.Params().Get("Parent"))
	println("parent from DB:")
	println(testQuestion.Parent.ID)
	println("===")

	i1, errr := strconv.ParseInt(c.Params().Get("Parent"), 10, 64)
	if errr != nil {
		panic(errr)
	}

	testQuestion.Parent.ID = int(i1)
	// Bind TestQuestion to the html form elements
	if err := c.Bind(testQuestion); err != nil {
		return errors.WithStack(err)
	}

	verrs, err := tx.ValidateAndUpdate(testQuestion)
	if err != nil {
		return errors.WithStack(err)
	}

	if verrs.HasAny() {
		// Make the errors available inside the html template
		c.Set("errors", verrs)

		// Render again the edit.html template that the user can
		// correct the input.
		return c.Render(422, r.Auto(c, testQuestion))
	}

	// If there are no errors set a success message
	c.Flash().Add("success", "TestQuestion was updated successfully")

	// and redirect to the test_questions index page
	return c.Render(200, r.Auto(c, testQuestion))
}

debug shows

===
parent from get:
3
parent from DB:
1
===

so buffalo actually get value from form, but did not update it.

How i can update this field?

@vasiliyaltunin

This comment has been minimized.

vasiliyaltunin commented Nov 29, 2018

I added more string into child table and it seems it just ignore parent field value, how i can fix this code so buffalo corretly link Parent value with value from parent table?

@vasiliyaltunin

This comment has been minimized.

vasiliyaltunin commented Nov 29, 2018

Also here is my List method

// List gets all TestQuestions. This function is mapped to the path
// GET /test_questions
func (v TestQuestionsResource) List(c buffalo.Context) error {
	// Get the DB connection from the context
	tx, ok := c.Value("tx").(*pop.Connection)
	if !ok {
		return errors.WithStack(errors.New("no transaction found"))
	}

	testQuestions := &models.TestQuestions{}

	// Paginate results. Params "page" and "per_page" control pagination.
	// Default values are "page=1" and "per_page=20".
	q := tx.Eager().PaginateFromParams(c.Params())

	// Retrieve all TestQuestions from the DB
	if err := q.Eager().All(testQuestions); err != nil {
		return errors.WithStack(err)
	}

	// Add the paginator to the context so it can be used in the template.
	c.Set("pagination", q.Paginator)

	return c.Render(200, r.Auto(c, testQuestions))
}

right now it just show all walues from parent table starting with first walue ignoring actual Parent field value

and here my template for list

<table class="table table-striped">
  <thead>
  <th>Parent</th>
  <th>ID</th>
  <th>Weight</th>
    <th>&nbsp;</th>
  </thead>
  <tbody>
    <%= for (testQuestion) in testQuestions { %>
      <tr>
        <td><%= testQuestion.Parent.Name %></td>
        <td><%= testQuestion.ID %></td>
        <td><%= testQuestion.Weight %></td>
        <td>
          <div class="pull-right">
            <a href="<%= testQuestionPath({ test_question_id: testQuestion.ID }) %>" class="btn btn-info">View</a>
            <a href="<%= editTestQuestionPath({ test_question_id: testQuestion.ID }) %>" class="btn btn-warning">Edit</a>
            <a href="<%= testQuestionPath({ test_question_id: testQuestion.ID }) %>" data-method="DELETE" data-confirm="Are you sure?" class="btn btn-danger">Destroy</a>
          </div>
        </td>
      </tr>
    <% } %>
  </tbody>
</table>

@vasiliyaltunin

This comment has been minimized.

vasiliyaltunin commented Nov 29, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment